上次聊到的直接插入排序在比較有序資料和待插入資料時,是通過依次遍歷的方式進行比較,當資料量比較大時,得考慮進一步優化;折半插入排序就是通過減少有序資料與待插入資料的比較次數,從而提公升效率。
1. 先來熟悉一下折半查詢
1.1 折半查詢演算法思想
折半查詢又稱二分查詢,僅適用於有序的順序表;
思想(假設順序表是公升序的):
重複以上過程,直到找到元素為止;或者找完所有資料為止,即查詢失敗;
1.2 折半查詢實現及解析
演算法**如下(在公升序順序表中查資料)
執行結果如下:
解析查詢步驟過程,如下:
圖中分別使用紅、綠、黃箭頭所指的資料分別高、中、低索引位,藍色為需要在順序表中查詢的數。
能查到資料的步驟:
上圖步驟說明:
查詢失敗時的情況:
上圖步驟說明:
1.3 分析折半查詢演算法效能
時間複雜度
如果傳入的資料規模為n,即有n個元素; 第一次在 n/2個元素中查詢,第二次在n/(22)個元素中查詢,第三次在n/(23)個元素中查詢,假如經過x次查詢到元素,則得到時間複雜度為o(log2n);
空間複雜度
因為在查詢過程中,用到了固定的幾個中間變數(low,mid,high),所以演算法過程中消耗的記憶體是乙個常量級別的,則空間複雜度為o(1);
穩定性
由於在演算法過程中只是查詢,不改變元素的位置,則折半查詢演算法是穩定的。
綜上所述,插入排序的時間複雜度為o(log2n),空間複雜度為o(1),是穩定演算法;
2. 搞明白折半插入排序
2.1 折半插入排序演算法思想
折半插入排序是對直接插入排序的優化,直接插入排序在比較過程中依次遍歷有序列表中的元素和待插入資料比較,而折半插入排序是將原來的依次遍歷有序列表換成折半查詢演算法,提公升比較效率,找到合適位置之後,對應的元素需要向後移位,然後將待插入元素插入到騰出的空位即可;重複到排序完成為止。
2.2 折半插入排序演算法實現與解析
**實現(公升序):
執行效果如下:
步驟解析如圖:
步驟說明:
圖中綠線框部分代表是已經排好序的列表,箭頭指的元素是下乙個待插入的元素,黃線框部分為剩下的無序元素。黃方塊為每次折半查詢到的mid位置,綠方塊表示最後有序列表騰出的位置。
2.3 折半插入排序演算法分析
時間複雜度
在演算法過程中有兩層迴圈,第一層需要遍歷所有元素,則時間複雜度為o(n);第二層迴圈中包含兩部分演算法,第一步是通過折半演算法找位置,時間複雜度在剛開始已經分析,為o(log2n);第二步是找到位置之後需要騰出空位,需要將對應元素移位,時間複雜度為o(n);則整體演算法的時間複雜度為外層迴圈的時間複雜度乘以內層迴圈的時間複雜度,去掉係數和常數,取大的,得出結果為o(n2);
空間複雜度
在演算法核心部分只採用了固定的幾個中間變數(i,j,low,mid,high,arrayb[0]),所以演算法過程中消耗的記憶體是乙個常量,則空間複雜度為o(1);
穩定性
由於在演算法過程中採用折半演算法找位置的,使用大於符號進行比較值,所以當遇到相等資料時,位置不會受到改變,則折半插入演算法是穩定的。
綜上所述,折半插入排序的時間複雜度為o(n2),空間複雜度為o(1),是穩定演算法;
乙個被程式搞醜的帥小伙,關注"code綜藝圈",跟我一起學~~~
插入排序和二分查詢
在插入資料時,用二分查詢法查詢資料,而不是一一比較。意外收穫 條件 資料從小到大,假設a a.length 為無窮大。二分查詢時,找不到,則左右索引最後相等,目標資料會比當前索引指向的資料小。public static void insertsortwithbinarysearch int a fo...
C語言 折半插入排序與二分查詢
標籤 c語言 插入排序 二分法 by 小威威 這部分內容我也是自學的,在網上找資料的時候覺得別人寫的文章很難理解,花了我不少時間。所以我寫了這一篇博文,希望能幫助你們更好理解二分插入排序的思想。畢竟這篇文章是入門級的 折半插入排序 binary insertion sort 是對插入排序演算法的一種...
二分查詢插入排序
採用二分查詢法,找到需要插入的index,以此改進傳統的插入排序方法,如下 include include include using namespace std const int num 20000 template void initarr vector arr template void p...