排序演算法的實現

2021-05-06 10:17:24 字數 1374 閱讀 3621

1、直接插入排序:把後面未排序部分的首個數插入到前面已排序部分的正確位置上去,直到全部排好順序。直接插入排序是穩定的,演算法時間複雜度o(n^2)。

2、shell排序:將要排序的一組數按某個增量g分成若干組,每組中記錄的下標相差g。對每組中全部元素進行直接插入排序,然後縮小增量g,在每組中再進行排序。當增量減到1時,整個要排序的數被分成一組,排序完成。shell排序是不穩定的,演算法時間複雜度可改進到o(n^1.25)左右。

注意一般的shell排序實現都是gap初始化為n/2,並採用除2的縮小增量策略。這裡初始化為不大小n的序列(1、4、13、40、121、...)中的最小值,並採用除以3的縮小增量策略,這可使排序加快20%~30%。內迴圈中的賦值從3次減少到1次。這裡增加了register修飾符,使這些變數儲存在暫存器中,在有些實現中,register宣告可以大大提高效能(有的高達40%)。

3、氣泡排序:對前面未排序部分每相鄰的兩個數進行比較和調整,讓較大的數上浮到後面已排序部分的開頭。氣泡排序是穩定的,演算法時間複雜度o(n^2)。

這裡設定了乙個flag,當元素序列本身就是有序時,直接返回,這可以加快排序過程。

4、快速排序:掃瞄一次元素並不斷地交換,使右邊部分的各個數都比左邊部分大。然後用同樣的方法處理這兩個子串行(用遞迴呼叫)。快速排序是不穩定的,最理想情況演算法時間複雜度o(nlgn),最壞為o(n^2),空間複雜度需要o(lgn)。

注意實現時要找乙個基準點的數,掃瞄完一遍後,左邊部分都會小於基準點數,右邊部分都會大於基準點數。因此開始時要暫存基準點數,掃瞄完一遍後把基準點插入到中間恰當的位置,這樣就分出了左邊部分和右邊部分,然後遞迴呼叫即可。

5、選擇排序:在後面未排序的部分中選擇最小的數插入到前面已排序部分的末尾。直到倒數第二個數和最後乙個數比較為止。選擇排序是不穩定的,演算法複雜度o(n^2)。

6、堆排序:是對選擇排序的改進。把陣列看作是二叉樹,b[k]的兩個子樹為元素x[2*k]與x[2*k+1]。堆是一棵樹,每個節點的數值不小於其後代節點的數值。初始時把要排序的數的序列看作是一棵順序儲存的二叉樹,調整它們的儲存順序,使之成為乙個堆,這時堆的根節點的數最大。然後將根節點與堆的最後乙個節點交換。然後對前面n-1個數重新調整使之成為堆。依此類推,直到只有兩個節點的堆,並對它們作交換,最後得到有n個節點的有序序列。堆排序是不穩定的,演算法時間複雜度o(nlgn)。

注意堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最後乙個元素交換位置。所以堆排序有兩個函式組成,一是建堆的調整函式,二是反覆呼叫實現排序的函式。

7、歸併排序:設兩個有序的子串行(相當於輸入堆)放在同一向量中相鄰的位置上r[low..m],r[m+1..high],先將它們合併到乙個區域性的暫存向量r1(相當於輸出堆)中,待合併完成後將r1複製回r[low..high]中。歸併排序是穩定的,演算法時間複雜度為o(nlgn),空間複雜度需要o(n)。

8、測試**。

排序演算法的實現

1.插入排序 演算法導論p3 insertsort.cpp created on 2012 7 9 author sangerhoo include using namespace std void insertsort int array,int n array i 1 key void arra...

排序演算法 選擇排序演算法實現

1 時間複雜度 o n 2 2 選擇排序主要操作是交換和比較 交換次數在0 n 1 總比較次數 n n 1 n 2 n 3 1 n n 1 2 因為交換需要的cpu時間 比較需要的cpu時間 當n比較少時,選擇比冒泡快,減少了不必要的交換,每次交換僅僅是最大值或者最小值與序列起始位置進行狡猾。3 演...

排序演算法 歸併排序演算法的實現

1 時間複雜度 最優情況 o n 最壞情況 o nlogn 將待排序的序列分成若干子串行,並且每個子串行是有序的,再將每個子串行兩兩進行排序,合併,最終整體有序。2 演算法步驟 1 先將序列拆分成兩個子串行 2 將兩個子串行之間進行排序,合成乙個 3 重複 1 2 過程,進行遞迴,直至每個序列個數為...