- 選擇排序
- 簡單選擇排序
- 在未排序序列中找出最小元素與序首元素交換位置,然后再剩下的未排序序列中找出最小元素與序列第二位元素交換位置,依次類推。
- T(n)=O(N^2)
for(int i=0;i<N;i++){
int min=i;
for(int j=i+1;j<N;j++){
if(a[j]<a[min])
min=j;
}
temp=a[i];
a[i]=a[min];
a[min]=temp;
}
堆排序
堆是一種特殊的二叉樹,子節(jié)點的值小于父節(jié)點的值
利用最大堆(最小堆)輸出堆頂元素,即最大值(最小值),然后再剩下的元素重新生成最大堆(最小堆),繼續(xù)輸出堆頂元素,直到輸出所有元素。
-
插入排序
- 簡單插入排序
- 將待排序序列分為已經(jīng)排好序的和未排好序的兩個部分。
- 初始狀態(tài)時,已排序序列僅包含第一個元素,將未排序序列中的元素逐一插入到已排序的序列中,經(jīng)過N-1次插入則排序完成。
- 插入排序是相對穩(wěn)定的排序,數(shù)值相同的兩個記錄不會發(fā)生相對位置上的變化
- T(n)=O(N^2)
for(int i=1;i<N;i++){
temp=a[i];
for(int j=i;(j>0)&&(temp<a[j-1]);j--){
A[j]=A[j-1] //j是從i開始的,已排好序的元素右移給騰出位置
}
A[j]=temp; //插入到合適的位置
}
-
希爾排序
- 簡單插入排序效率不高的重要原因是每次只交換相鄰的兩個元素,這樣一次只能消去一對錯位的元素。希爾排序試圖通過每次交換一定距離的兩個元素,達到排序效率上的提升。
希爾排序將待排序的一組元素按一定間隔分為若干個序列,分別進行插入排序,開始時設置的間隔較大,在每輪排序中間隔逐步減小,直到間隔為1,也就是最后一輪排序。
-
交換排序
- 冒泡排序
- 對元素個數(shù)為N的待排序序列,共進行N-1次循環(huán)。
- 在第K次循環(huán)中,對從第1個元素到第N-K個元素從前往后進行比較,每次比較相鄰的兩個元素,若前一個元素大于后一個元素則交換位置,否則保持位置不變,這樣一次循環(huán)下來就把第K大的元素放到第N-K的位置上,稱為第K趟的冒泡。
- T(n)=O(N^2)
- 冒泡排序也是一種穩(wěn)定的排序
for(int i=0;i<N;i++){
flag=0; //標記這次循環(huán)是否有發(fā)生交換,若無則說明整個序列有序
for(int j=0;j<N-i-1;i++){
if(a[j+1]<a[j]){
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
flag=1;
}
}
if(!flag)
break; //若沒有發(fā)生交換,則跳出循環(huán)
}
快速排序
將未排序元素根據(jù)基準分為兩個子序列,然后對兩個子序列用類似的方法排序。
T(n)=O(NlogN)
至少需要O(logN)深度的棧空間
-
歸并排序
- 將大小為N的序列看成N個長度為1的子序列,接下來將相鄰子序列進行歸并操作,形成[N/2]個長度為2(或1)的有序子序列,然后再進行相鄰子序列的兩兩歸并操作,如此一直循環(huán)知道只剩下一個長度為N的序列。
- 需要申請額外空間用于放置兩個子序列歸并之后的結果
- T(n)=O(NlogN)
-
桶排序
- 已知N個關鍵字的取值范圍是0-M-1;而M比N小得多,則桶排序算法將為關鍵字的每個可能取值建立一個桶,在掃描N個關鍵字時,將每個關鍵字放入相應的桶中,然后按桶的順序收集一遍就自然有序了。
- 桶排序效率比一般排序算法高,額外條件是已知關鍵字的范圍i,并且關鍵字在此范圍內是可列的個數(shù)還不能超過內存空間所能承受的限度。
基數(shù)排序
基數(shù)排序是對桶排序的一種推廣,所考慮的待排序記錄包含不止一個關鍵字,例如對一副牌的整理。
- 歸納
- 排序算法性能從低到高的順序大致為:冒泡排序、插入排序、選擇排序、希爾排序、快速排序。但這個優(yōu)劣順序不是絕對的,在不同的情況下,甚至可能出現(xiàn)完全的性能逆轉。
- 對于序列初始狀態(tài)基本有正序,可選擇對有序性較敏感的如插入排序、冒泡排序、選擇排序等方法
- 對于序列長度 比較大的隨機序列,應選擇平均時間復雜度較小的快速排序方法。