選擇排序每次遍歷一遍陣列,找出最小的數,然後跟陣列的第乙個元素交換。再從剩下的元素中重複此步驟直至陣列排序完畢。時間複雜度與輸入資料無關,為o(n^2)。
}}每次從首元素開始,從左到右交換相鄰且逆序的元素,一直交換到尾元素時即完成一輪迴圈,此時末尾元素即為最大值。接著在除尾元素外的剩餘元素中繼續上述迴圈,直至排序完成。時間複雜度為o(n^2)。
可以優化的一點:當在一趟迴圈中沒有元素交換,就說明陣列已有序,結束排序。
下圖為一趟交換示意圖,最後的 5 為排完序部分:
}主要思想是將陣列分成左右兩部分,各自排序後再合併起來。子陣列排序也是分成兩部分,如此遞迴下去。因其分治策略每次劃分的子陣列規模都接近相等,故即使在最壞情況下,依然能保持時間複雜度為o(nlogn)。在合併的時候需要乙個與原陣列大小相等的輔助陣列(這裡的**優化為1/2大小),故額外空間複雜度為o(n)。
// 合併左右兩個有序陣列
void
merge
(vector<
int>
& a,
int low,
int mid,
int high)
// 如果剩下的是前半部分,則把這部分填進陣列
// 否則因為剩下的是後半部分,已在原陣列且有序,無需處理
if(pa < tmp.
size()
)}void
mergesort
(vector<
int>
& a,
int low,
int high)
上面的**是把逐層遞迴下來,那麼我們直接從最底層開始,合併相鄰兩個元素形成乙個陣列,再把這些陣列相鄰的合併,逐漸往頂層走,就形成了非遞迴方法。需要注意的是資料最後面沒法形成完整兩個陣列的情況。
void
mergesort
(vector<
int>
& a)
}}
每次從未排序部分選取第乙個元素插入左邊已有序部分,形成新的有序部分,如此迴圈插入直至整體有序。插入的方法為從右到左相鄰逆序即交換,直到合適位置。
在輸入資料已有序情況下,只需進行n次比較,時間複雜度為o(n),若輸入完全逆序,則時間複雜度為o(n^2), 平均複雜度為o(n^2)。
下圖左邊為已有序部分,將2插入其中。
}}對於大規模的陣列,插入排序很慢,因為它只能交換相鄰的元素,每次只能將逆序數量減少 1。希爾排序是簡單插入排序經過改進之後的乙個更高效的版本,也稱為縮小增量排序。
它通過交換不相鄰的元素,每次可以將逆序數量減少大於 1。隨著陣列有序性的不斷提高,執行時間將會銳減。
希爾排序使用插入排序對間隔 h 的序列進行排序。通過不斷減小 h,最後令 h=1,就可以使得整個陣列是有序的。
}}希爾排序在最壞情況下時間複雜度為o(n^2) ,但隨著逆序對的減少,執行時間會越來越短,最終時間複雜度低於o(n^2)。同時,希爾排序的好壞嚴重依賴於所選的增量序列。
冒泡 選擇 插入 希爾排序
include include include using namespace std template void print const t a,int n 氣泡排序 每次迴圈總是將最大元素移到隊尾 o n 2 穩定的排序演算法 templatevoid bubblesort t a,int n ...
排序演算法及分析(插入 希爾 選擇 冒泡)
假如我們要從小到大排序,下面幾種簡單的演算法可以處理規模不大的資料,我寫成函式形式。一 插入排序 思想就是 從左到右對每個數,每次在它前面找到乙個合適的位置把它插進去。void insertsort int a,int n c是比較次數,m是移動次數,則 最好情況 c n 1 m 0 最壞情況 c ...
陣列排序(冒泡,選擇,插入,希爾)
package org.owen public class sortall system.out.println 氣泡排序的結果 maopao i system.out.println system.out.println 選擇排序的結果 xuanze i system.out.println sy...