插入排序基本思想
每次將一個待排序的記錄按其關鍵字大小插入到前面已經拍好序的子文件的適當位置,直到全部記錄插入完成爲止。
直接插入排序
基本思想
直接插入排序的基本操作是將一個記錄插入到已排好序的有序表中,從而得到一個新的有序表。即假設待排序的記錄存放在數組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語言描述》、《大話數據結構》