文章儲存在github
,網速不佳的朋友,請看《基礎排序演算法詳解與優化》 或者 來我的技術小站 godbmw.com
常見的基礎排序有選擇排序、氣泡排序和插入排序。眾所周知,他們的時間複雜度是 o(n*n)。
但是,現在要重新認識一下基礎排序演算法,尤其是「插入排序」:在近乎有序的情況下,插入排序的時間複雜度可以降低到 o(n)的程度。
因此,在處理系統日誌的任務中,因為日誌記錄是按照時間排序,但偶爾會有幾條是亂序,此時使用插入排序再好不過。而對於高階排序演算法,乙個常見的優化就是利用插入排序做區域性資料排序優化。
排序演算法被封裝在了sortbase.h
中的sortbase
命名空間中,以實現模板化和防止命名衝突。如下圖所示:
假設從小到大排序,那麼,剛開始指標指向第乙個資料,選擇從當前指標所指向資料到最後乙個資料間最小的資料,將它放在指標位置。
指標後移一位,重複上述步驟,直到指標移動到最後乙個資料。
這種重複保證了每次,指標前面的資料都是從小到大排好順序的資料。所以,從頭到尾掃瞄一遍,自然排好序了。
**如下:
template void selectionsort(t arr, int n)
}swap(arr[i], arr[minindex]);
}}
假設排序是從小到大排序。
我一直感覺氣泡排序是和選擇排序反過來了(如果說錯請指正)。因為選擇排序是每次選擇最小的資料,放到當前指標位置;而氣泡排序是把不停交換相鄰資料,直到把最大的資料「冒泡」到應該到的位置。
在實現過程中,因為需要不停交換相鄰兩個資料,因此,消耗了很多額外時間。
template void bubblesort(t arr, int n)
}n = newn; // 不再考慮 newn 後的資料
} while (newn > 0);
}
插入排序容易和上面兩個演算法搞混。可以模擬打撲克牌時候的對撲克牌進行排序:我們會先排序前 1 張、然後是前 2 張、前 3 張 ... 一直到前 n 張。演算法實現顯然是雙重迴圈,如下所示:
template void insertionsort(t arr, int n) else }}}
顯然,插入排序也能在區域性排好序的情況下跳出迴圈(**中的優化),以減少演算法消耗時間。
然而上述演算法其實跑分並比不上選擇排序,因為swap(arr[j], arr[j - 1]);
這行**交換了一次,相當於賦值 3 次,在大資料量情況下,比較消耗時間。
優化: 內層迴圈,每次儲存arr[i]
, 在檢測到當前資料大於arr[i]
的時候,後移一位當前元素arr[j] = arr[j-1];
。當跳出內層迴圈時,直接將儲存的arr[i]
賦值給arr[j]
即可。
template void insertionsort(t arr, int n)
arr[j] = e;
}}
首先利用sorttesthelper::generaterandomarray
函式生成大量無序隨機資料,然後進行排序和時間測定。**如下:
#include #include "sorthelper.h"
#include "sortbase.h"
#include "sortadvance.h"
using namespace std;
int main()
執行結果如下圖所示:
除了大量無序隨機資料,類似於系統日誌的資料就是基本有序的大量資料。此時,測試**如下:
#include #include "sorthelper.h"
#include "sortbase.h"
#include "sortadvance.h"
using namespace std;
int main()
如圖所示,插入排序的只用了 0.002 秒。在這種資料情況下,插入排序的時間複雜度近似 o(n),絕對快於高階排序的 o(nlogn)。除此之外,還保證了穩定性。
本篇部落格是總結於慕課網的《學習演算法思想 修煉程式設計內功》的筆記,liuyubobobo 老師人和講課都很 nice,歡迎去買他的課程。
基礎排序演算法詳解與優化
文章儲存在github,網速不佳的朋友,請看 基礎排序演算法詳解與優化 或者 來我的技術小站 godbmw.com 常見的基礎排序有選擇排序 氣泡排序和插入排序。眾所周知,他們的時間複雜度是 o n n 但是,現在要重新認識一下基礎排序演算法,尤其是 插入排序 在近乎有序的情況下,插入排序的時間複雜...
基礎排序演算法詳解與優化
文章儲存在github,網速不佳的朋友,請看 基礎排序演算法詳解與優化 或者 來我的技術小站 godbmw.com 常見的基礎排序有選擇排序 氣泡排序和插入排序。眾所周知,他們的時間複雜度是 o n n 但是,現在要重新認識一下基礎排序演算法,尤其是 插入排序 在近乎有序的情況下,插入排序的時間複雜...
基礎排序演算法優化
這篇部落格,主要是最近學習演算法導論時的一些收穫,是關於直接選擇排序,直接插入排序,二分查詢的一些優化。資料結構課本上的直接選擇排序就是每次選出乙個最小的拿到最前面來 function straightselectsort arr if k i 但是我們考慮一下,有沒有可以優化的地方呢?既然我們每次...