本文主要比較一下各種排序的效能(平均時間複雜度和最差情況)和基本實現。
這個預設按照從小到大排列,輸入的資料可以重複,假設輸入的陣列為a,下標從0到n-1
注意在比較演算法複雜度時,我們會關注鍵值的比較次數和交換次數。
1、氣泡排序
氣泡排序如果不是因為名字比較好記,沒有任何優勢。它的思路是一趟又一趟的比較陣列(或者鍊錶也可以)中相鄰的兩個元素,如果前乙個比後乙個大,則交換。這樣,每一輪之後,最大的那個元素被「沉」到陣列的最後去。
void bubble_sort(int a, int n)
可以發現,在平均情況和最差情況是,鍵值的比較次數和交換次數都是o(n^2)
在最好情況下,鍵值的比較次數還是o(n^2),但是**經過優化後鍵值的交換次數為o(n)
public
void
bubblesort(int arr)
}if(didswap == false)
return;
}
}
參見
同時,氣泡排序還是乙個穩定的演算法。
2、插入排序
插入排序的思想是對於乙個a[i],我們假設它之前的都已經排序好了,這時關鍵是向前尋找a[i]的位置,j=i-1~0,比較a[i]和a[j],如果a[j]大,則a[j]向後移,直到a[j]小時,就是a[i]的位置。
void insertion_sort(int a, int n)
}
插入排序是對氣泡排序的改進,也是穩定的演算法。
最差的情況是逆序(從大到小排列)時間複雜度是o(n^2)
3、希爾排序
以d間隔進行排序,為了每次不止消除乙個逆序對。
d=2^k-1(比較好的 d)
void shell_sort(int a, int n)
}}
4、選擇排序
對當前的下標位置i時,我們要找到i+1到n-1中的最小的下標min_i與i位置的元素交換
void selection_sort(int a, int n)
上面的問題是多使用了乙個額外的陣列來儲存。
另外乙個種堆排序,
#define leftchild(i) (2
*(i)+1) //以0為起點的堆
void percdown(int a, int i, int n)
a[parent]=tmp;
}void heap_sort(int a, int n)
}
優點,堆排序是一種在位的排序方法,適合資料量非常大的場合。
6、快速排序
在資料量一般的情況下,是效能最好的排序方法。主要的思想是分治,它本身有很多trick,stl裡中的sort就是使用快速排序的,它的原始碼也值得好好研究下。這裡主要說下主要的幾個trick
1、主元pivot的選擇,先使用乙個median3的函式,選擇出left(0),right(n-1),center三個位置上的中位數,並將中位數放在right-1的位置。(這樣只要考慮a[left+1,right-2]事實證明主元的選擇對效能有較大影響,這種方式較好。
2、i從left開始,j從right-1開始移動,直到兩者相交
3、停止的時候,交換a[i]和a[right-1],遞迴左右兩個子串行
4、當序列的長度小於閾值時,不遞迴而使用才插入排序 ,這樣也能顯著調高速度
//swap two numbers
void swap(int *a, int *b)
//choose the median of left, center and right
int median3(int *a, int left, int right)
//insertion sort ---for small size array and index array
void insertion_sort(int *a, int n)
} void quicksort(int *a, int left, int right)
if(ia+i,a+j);
else
break
; }
swap(a+i,a+right-1);
quicksort(a,index_a,left,i-1);
quicksort(a,index_a,i+1,right);
}else
insertion_sort(a+left,right-left+1);
}
具體的效能比較可以參考
7、位排序
還有乙個處理大資料的方法,參見之前的一篇文章
海量資料處理
排序演算法實現及總結
1 氣泡排序 時間複雜度 最壞情況和平均情況 o n 最好情況 o n 屬於穩定排序 void bubble sort vector int nums if flag 0 break return 2 選擇排序 時間複雜度 最壞情況,最好情況,平均情況 o n 不是穩定排序 適用於資料量小的或有部分...
各種排序演算法總結
注 以下所講排序,以公升序排序為例!選擇排序 作者思路 在一組數中,選擇第乙個數標記為最小值,在剩下的數中找比它小的數,若找到則交換兩數,標記新的 最小值 然後繼續往下找,這樣一趟下來就可以找到一組數中第二小的值,第二次以第二個數作為最小值,如此迴圈下去。這是最簡單 最基礎的一種排序演算法。例子 1...
各種排序演算法總結
1 插入排序 void insertsort int a,int n a j 1 key 插入排序是穩定的排序,平均和最壞時間複雜度是o n 2 最好的時間複雜度是o n 對應於全部排好序的情況。2 氣泡排序 void bubblesort int a,intn 氣泡排序是穩定的排序,平均和最壞時間...