直接插入排序
難度:★★☆☆☆
基本思想
利用歸併操作實現排序,將兩個順序序列合併成一個順序序列。先利用遞歸分治,使得最初單個元素的序列合併,合併後2個元素的有序序列,然後多個序列合併成更大的序列,依次累積成一個序列,最終實現排序.
兩個歸併操作的流程
(1)構建一個臨時序列,大小爲兩個序列之後,用來保存歸併的數據
(2)記錄兩個序列的初始下標
(3)比較序列1第一個元素與序列2第一個元素,如果是小到(4),否則(5)
(4)保存序列1當前元素到臨時序列,1下標增大,直到下標對應元素比序列2當前大,到(6)
(5)保存序列2當前元素到臨時序列,1下標增大,直到下標對應元素比序列1當前大,到(6)
(6)如果其中一個序列的下標走到最後一位,到(7),否則(3)
(7)把沒有歸併的完的序列後面的元素拼接到臨時臨時序列
算法圖解
- 臨時序列爲合併序列
- 序列2與序列1合併,圖解中位置表示大小關係,越靠右越大,因爲序列1和2都是有序,大小同樣對應其在序列中位置
程序實現
public class MergeSort {
static void mergeShort(int[] data,int start,int end) {
if(start>=end) {return;}
int mid = (start+end)/2;
mergeShort(data,start,mid);
mergeShort(data,mid+1,end);
merge(data,start,mid,end);
}
static void merge(int[] data,int start,int mid,int end) {
int[] tmp =new int[data.length];
int p=start,p2=mid+1,k=start;
while(p<=mid&&p2<=end) {
if(data[p]<=data[p2]) {
tmp[k++]=data[p++];
}else {
tmp[k++]=data[p2++];
}
}
while(p<=mid)tmp[k++]=data[p++];
while(p2<=end)tmp[k++]=data[p2++];
for(k=start;k<=end;k++) {
data[k]=tmp[k];
}
}
public static void main(String[] arg) {
System.out.print("start..\n");
int[] data ={1,3,5,4,0,6,3,4,8,5,2};
outPut(data);
mergeShort(data,0,data.length-1);
outPut(data);
}
private static void outPut(int[] a){
System.out.print("\n out:");
for(int i=0;i<a.length;i++) {
System.out.print(a[i]+" ");
}
System.out.print("\n");
}
}
排序算法穩定性
歸併排序是穩定的排序.即相等的元素的順序不會改變.如輸入記錄 1(1) 3(2) 2(3) 2(4) 5(5) (括號中是記錄的關鍵字)時輸出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按輸入的順序.這對要排序數據包含多個信息而要按其中的某一個信息排序,要求其它信息儘量按輸入的順序排列時很重要。歸併排序的比較次數小於快速排序的比較次數,移動次數一般多於快速排序的移動次數。