歸併排序

直接插入排序

難度:★★☆☆☆

基本思想

利用歸併操作實現排序,將兩個順序序列合併成一個順序序列。先利用遞歸分治,使得最初單個元素的序列合併,合併後2個元素的有序序列,然後多個序列合併成更大的序列,依次累積成一個序列,最終實現排序.

兩個歸併操作的流程
(1)構建一個臨時序列,大小爲兩個序列之後,用來保存歸併的數據
(2)記錄兩個序列的初始下標
(3)比較序列1第一個元素與序列2第一個元素,如果是小到(4),否則(5)
(4)保存序列1當前元素到臨時序列,1下標增大,直到下標對應元素比序列2當前大,到(6)
(5)保存序列2當前元素到臨時序列,1下標增大,直到下標對應元素比序列1當前大,到(6)
(6)如果其中一個序列的下標走到最後一位,到(7),否則(3)
(7)把沒有歸併的完的序列後面的元素拼接到臨時臨時序列

算法圖解

  1. 臨時序列爲合併序列
  2. 序列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 是按輸入的順序.這對要排序數據包含多個信息而要按其中的某一個信息排序,要求其它信息儘量按輸入的順序排列時很重要。歸併排序的比較次數小於快速排序的比較次數,移動次數一般多於快速排序的移動次數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章