【算法拾遺(java描寫敘述)】--- 插入排序(直接插入排序、希爾排序)
阿新 • • 發佈:2017-07-31
ecan itblog insert med image java程序 can rip title
插入排序基本思想
每次將一個待排序的記錄按其keyword大小插入到前面已經拍好序的子文件的適當位置,直到全部記錄插入完畢為止。
直接插入排序
基本思想
直接插入排序的基本操作是將一個記錄插入到已排好序的有序表中。從而得到一個新的有序表。即如果待排序的記錄存放在數組R[1······n]中,排序過程中,R被分成兩個子區間R[1······i]和R[i+1······n],當中。R[1······i]是已經排好序的有序區;R[i+1······n]是當前未排序的部分。
將當前無序區的第一個記錄R[i+1]插入到有序區R[1······i]的適當位置,使R[1······i+1]變為新的有序區,每次插入一個數據,直到全部的數據有序為止。
java程序
/************************* * * 直接插入排序 * *************************/ public class InsertSort { private void insertSort(int[] datas) { if (datas == null || datas.length < 2) return; int i, j, insertData; for (i = 1; i < datas.length; i++) { insertData = datas[i];// 要插入的變量 for (j = i - 1; j >= 0 && insertData < datas[j]; j--) datas[j + 1] = datas[j]; datas[j + 1] = insertData;// 將要插入的數據放置到正確的位置 } } public static void main(String[] args) { int[] datas = new int[] { 6, 5, 3, 1, 8, 7, 2, 4 }; System.out.println("********排序前********"); for (int i = 0; i < datas.length; i++) { System.out.print(datas[i] + ","); } InsertSort insertSort = new InsertSort(); insertSort.insertSort(datas); System.out.println("\n********排序後********"); for (int i = 0; i < datas.length; i++) { System.out.print(datas[i] + ","); } } }
性能分析
- 時間復雜度
- 直接插入排序屬於就地排序,是一種穩定的排序方法。
希爾排序
基本思想
先取一個小於n的整數d1作為第一個增量,把文件的全部記錄分成d1個組,全部距離為d1的倍數的記錄放在同一個組中,在各組內進行插入排序;然後。取第二個增量d2 < d1,反復上述的分組和排序,直至所取得增量dt = 1(dt < dt-1 < ······ < d2 < d1),即全部記錄放在同一個組中進行直接插入排序為止。
java程序
/************************* * * 希爾排序 * *************************/ public class ShellSort { private void shellSort(int[] datas) { if (datas == null || datas.length < 2) return; int temp;// 暫存變量 int dataLength;// 步長 int pointer;// 進行處理的位置 dataLength = datas.length / 2;// 初始化步長 while (dataLength != 0) { for (int j = dataLength; j < datas.length; j++) { temp = datas[j]; pointer = j - dataLength; while (pointer >= 0 && temp < datas[pointer]) { datas[pointer + dataLength] = datas[pointer]; pointer = pointer - dataLength; } datas[pointer + dataLength] = temp; } dataLength = dataLength / 2; } } public static void main(String[] args) { int[] datas = new int[] { 6, 5, 3, 1, 8, 7, 2, 4 }; System.out.println("********排序前********"); for (int i = 0; i < datas.length; i++) { System.out.print(datas[i] + ","); } ShellSort shellSort = new ShellSort(); shellSort.shellSort(datas); System.out.println("\n********排序後********"); for (int i = 0; i < datas.length; i++) { System.out.print(datas[i] + ","); } } }
性能分析
希爾排序的運行時間依賴於增量序列(步長)的選取。好的增量序列有例如以下特點:
- 最後一個增量必須為1
- 應該盡量避免序列中的值(尤其是相鄰的值)互為倍數的情況。
希爾排序的時間性能要因為直接插入排序,原因例如以下:
- 當文件初態基本有序時直接插入排序所需的比較和移動次數均較少。
- 在希爾排序開始時增量較大,分組較多,每組的記錄數目少,故各組內直接插入較快,後來增量di逐漸縮小,分組數逐漸降低。而各組的記錄數目逐漸增多,但因為已經按di-1作為距離排過序,使文件較接近於有序狀態。所以新的一趟排序過程也較快。
因此,希爾排序在效率上較直接插入排序有較大的改進。
希爾排序是一種不穩定的排序方法
參考資料:《數據結構與算法分析——java語言描寫敘述》、《大話數據結構》
【算法拾遺(java描寫敘述)】--- 插入排序(直接插入排序、希爾排序)