本節主要分析插入排序演算法的直接插入排序和希爾(shell)排序(又稱縮小增量排序)。
1. 直接插入排序
該排序是最簡單的排序方法,其基本思想是:假設待排序的記錄存放在陣列r[1..n]中。初始時,r[1]自成1個有序區,無序區為r[2..n]。從i=2起直至i=n為止,依次將r[i]插入當前的有序區r[1..i-1]中,生成含n個記錄的有序區。
直接插入排序演算法:
void insert_sort(sqlist *s)
s->data[j + 1] = s->data[0]; /* 在正確位置上進行插入 */
} output_list(*s); /* 測試用,檢視每一趟排序結果 */
}}
直接插入排序從第2個元素開始,用該元素和其前面的元素進行比較,當待排記錄比前乙個小時該趟要發生資料移動,首先將待排元素複製乙份作為比較時用,然後將待排元素前乙個元素後移,覆蓋在待排元素的位置(因為剛才已經比較過一次了,前乙個元素大,要後移),再將待排元素和前面的比較,若待排元素小就再將和其比較的元素後移,直到有乙個元素小於或等於待排元素,此時找到正確位置,將待排元素插入,一趟排序完畢。再將第3、4······到最後乙個元素重複上述步驟,此時排序完畢。
直接插入排序分析:
從上面敘述可見,直接插入排序演算法簡潔,容易實現。從空間來看,只需要乙個輔助空間,從時間看,基本操作為:比較兩個關鍵字大小何移動記錄。花時間最少情況:待排序列按關鍵字非遞減有序排列(正序),只需比較關鍵字次數達最小值n-1,記錄不需移動。花時間最多情況:待排序列按關鍵字非遞增有序排列(逆序),總比較次數達最大值(n+2)(n-1)/2,記錄移動次數也達到最大值(n+4)(n-1)/2。考慮隨機情況:可取上述最小和最大值的平均值作為直接插入排序是所需進行關鍵字的比較次數和移動次數,約為n方/4。故直接插入排序時間複雜度為o(n方)。
2. 希爾排序(shell』s sort)
希爾排序也是一種插入排序類的方法,其在時間效率上角前述幾種排序方法右較大改進。從上面直接插入排序分析可知,若待排記錄序列按關鍵字基本有序時,直接插入排序效率可大大提高。另一方面,直接插入排序演算法簡單,在n值很小時效率也比較高。希爾排序正是從這兩點分析出發對直接插入排序進行改進的到的一種插入排序演算法。
希爾排序演算法基本思想:先取乙個小於n的整數d1作為第乙個增量,把檔案的全部記錄分成d1個組。所有距離為dl的倍數的記錄放在同乙個組中。先在各組內進行直接插人排序;然後,取第二個增量d2
1重複上述的分組和排序,直至所取的增量dt=1(dt
t-l<…2
1),即所有記錄放在同一組中進行直接插入排序為止。
希爾排序演算法:
void shell_sort(sqlist *s)
} output_list(*s); /* 測試用,檢視每一趟排序結果 */
} while (d > 1);
}
shell排序的增量暫時沒有最好的的序列,增量序列有個種取法,但應注意:應使增量序列中的值沒有除1之外的公因子,並且最後乙個增量值必須為1.
有人通過大量實驗得出結論:當n較大時,比較和移動的次數約在nl.25到1.6n1.25之間。
3. 兩種演算法比較
①當檔案初態基本有序時兩種排序所需的比較和移動次數均較少。
②當n值較小時,n和n2的差別也較小,即直接插入排序的最好時間複雜度o(n)和最壞時間複雜度0(n2)差別不大。
③在希爾排序開始時增量較大,分組較多,每組的記錄數目少,故各組內直接插入較快,後來增量di逐漸縮小,分組數逐漸減少,而各組的記錄數目逐漸增多,但由於已經按di-1作為距離排過序,使檔案較接近於有序狀態,所以新的一趟排序過程也較快。
因此,希爾排序在效率上較直接插人排序有較大的改進。
希爾排序是不穩定的。根據shell排序演算法分析,兩個相同關鍵字在排序前後的相對次序很可能發生變化。
排序演算法之插入排序
排序演算法之插入排序 1 插入排序的思想 假設在乙個有序序列中 e 0 e i 1 這i 個元素已經排好序,則當要將第 i 1個元素 e 插入該序列時,只需將第 i 1個元素與從 e 0 開始到e i 1 元素進行比較,當發現第 j個元素 e j 在序列中應在 e 前,且 e j 1 應在e 後時,...
排序演算法之插入排序
排序演算法之插入排序 1 插入排序的思想 假設在乙個有序序列中 e 0 e i 1 這i 個元素已經排好序,則當要將第 i 1個元素 e 插入該序列時,只需將第 i 1個元素與從 e 0 開始到e i 1 元素進行比較,當發現第 j個元素 e j 在序列中應在 e 前,且 e j 1 應在e 後時,...
排序演算法之插入排序
將乙個數插入到一組已經排好序的序列中,保持插入後序列排序關係不變,這就是插入排序。將乙個陣列分為兩個部分,前一部分為已排序,後一部分為亂序,每次將亂序部分第乙個元素插入到有序部分中,從插入點開始有序部分元素依次後移,如此重複直至亂序元素個數為0,則完成整個排序過程。插入排序演算法 void inse...