選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
---維基百科
選擇排序有兩個鮮明的特點:
- 運行時間和輸入無法。在一個數組中找到最小項的過程,對于下一個查找過程并不能提供很多有效的信息。
- 數據移動是最小的。
public class SelectSort {
public static void main(String [] args){
Integer a[] = {1,9,8,3,4,5} ;
sort(a) ;
for(int i = 0 ; i < a.length ; i++){
System.out.print(a[i]+", ");
}
}
private static boolean less(Comparable v, Comparable w){
return v.compareTo(w)<0 ;
}
private static void exch(Comparable [] a, int i , int j){
Comparable t = a[i] ;
a[i] = a[j] ; a[j] = t ;
}
/**
* 1. 運行時間和輸入數據沒有關系。本次的比較結果對下次比較并沒有什么幫助<p>
* 2. 數據移動是最少的。數據交換發生N次
* @param a 要進行比較的數組
*/
private static void sort(Comparable [] a){
int N = a.length ;
for( int i =0 ; i< N ; i++){
int min = i ;
for(int j = i+1 ; j<N ; j++){
if(less(a[j],a[min])) min = j ;
}
exch(a,i,min) ;
}
}
}
堆排序是對選擇排序的一種改進。彌補了選擇排序不帶有“記憶性”的缺失。
堆是具有下列性質的完全二叉樹:每個結點的值大于或者等于其左右孩子節點,稱為大頂堆;或者每個節點的值小于或者等于左右孩子結點的值,稱為小頂堆。
根據完全二叉樹性質:如果i=1,則結點i是二叉樹的根,無雙親;如果i>1,其雙親是節點 ?i/2?。
public class HeapSort
{
private static int[] a;
private static int n;
private static int left;
private static int right;
private static int largest;
public static void buildheap(int []a){
n=a.length-1;
for(int i=n/2;i>=0;i--){
maxheap(a,i);
}
}
public static void maxheap(int[] a, int i){
left=2*i;
right=2*i+1;
if(left <= n && a[left] > a[i]){
largest=left;
}
else{
largest=i;
}
if(right <= n && a[right] > a[largest]){
largest=right;
}
if(largest!=i){
exchange(i,largest);
maxheap(a, largest);
}
}
public static void exchange(int i, int j){
int t=a[i];
a[i]=a[j];
a[j]=t;
}
public static void sort(int []a0){
a=a0;
buildheap(a); //初始化大頂堆
for(int i=n;i>0;i--){
exchange(0, i); //將最大數交換到最后
n=n-1;
maxheap(a, 0); // 建立大頂堆
}
}
public static void main(String[] args) {
int []a1={5,4,3,2,1};
sort(a1);
for(int i=0;i<a1.length;i++){
System.out.print(a1[i] + " ");
}
}
}
可視化過程:
http://www.cs.usfca.edu/~galles/visualization/Algorithms.html
http://jsdo.it/norahiko/oxIy/fullscreen
http://zh.visualgo.net/zh