1. 程式人生 > >歸並排序:步驟講解與代碼實現

歸並排序:步驟講解與代碼實現

.com system tar 大致 有序 數組 pub 比較 使用

歸並排序

  在一些常用的排序中,歸並排序在時間開銷上來說可以是排序中的最佳實踐之一(時間復雜度=n*log n),今天我們就來看看歸並是如何實現的。

  歸並排序大致可以分為兩步:

    1、將數組從中間分開,對兩邊分別排序。

    2、將兩個有序的數組進行合並。

  所以實現歸並排序主要也就是解決這兩個問題。

  下圖是歸並排序的大致步驟,紅線代表將數組拆開,藍箭頭代表將拆後的數組分別處理,紅箭頭代表將數組排序後返回

技術分享

問題1:如何將數組分開,並進行分別排序?

答:使用遞歸實現

問題2:如何將兩個有序的數組進行合並排序?

假設如上圖的第二行中,需要合並(2,4,5,8)和(

1,3,6,7)兩個數組。

1,因為這兩個數組都是增序的,只需要比較倆個數組的第一個數,那麽比較小的數必然是兩數組中最小的數

  例:比較(2,4,5,8)的2 和(1,3,6,7)的1,那麽1必然是兩數組中最小的數。

2,將這個數放入一個新的數組。

  例:將1放入數組a[]中,兩數組還有(2,4,5,8)的2 和(3,6,7)

3,再次重復第1步。

.....

如此比較直到其中一個數組結束,將另一個數組剩下的值全部放入數組a

那麽數組a便是排好序的數組。

代碼實現:

public class MergesSort {
    //排序函數,target為要排序的數組,
       
// begin和end為要排序的區間的開始和結束坐標 public void mergeSort(int target[],int begin,int end){ //當要排序的數組區間只有一個數時直接返回 if((end-begin)==0){ return ; } //當排序的數組區間有兩個數時,對這兩個數進行比較 if((end-begin==1)){ sortS2B(target,begin,end); return ; }
//當要排序的數組大於2個時,我們就分割此數組的區間,分別排序; int mid=(begin+end)/2; mergeSort(target,begin,mid); mergeSort(target,mid+1,end); //將排序好的倆數組的區間進行合並排序 //創建一個數組用於存放排好序的數組,大小就是區間大小 int temp[]=new int[end-begin+1]; //存放第一個數組的開始坐標 int p1=begin; //存放第二個數組的開始坐標 int p2=mid+1; //存放temp數組最近一次存放的數的坐標,初始為0 int p3=0;
      
while(p1<=mid&&p2<=end){ //將小的數存到temp數組 if(target[p1]<target[p2]){ temp[p3]=target[p1]; p3++; p1++; }else{ temp[p3]=target[p2]; p3++; p2++; } } //檢查是否還有沒有插入的 while(p1<=mid){ temp[p3]=target[p1]; p3++; p1++; } while(p2<=end){ temp[p3]=target[p2]; p3++; p2++; } //將排好的數組temp與原target的替換 System.arraycopy(temp, 0, target, begin, temp.length); }
//將數組target的a和b坐標的兩個數按small to big從小到大排序 public void sortS2B(int target[],int begin,int end){ //如果begin>end,進行交換 if(target[begin]>target[end]){ int temp=target[begin]; target[begin]=target[end]; target[end]=temp; } return ; } public static void main(String[] args) { MergesSort ms=new MergesSort(); int a[]={8,-6,2,-7,9,-23,2,7,4,67,1,8}; //註意第三個參數是數組的結束坐標,應該因為數組是從0開始的,所以結束的坐標需要數組的長度-1 ms.mergeSort(a,0,a.length-1); int i=0; while(i<a.length){ System.out.print(a[i++]+" "); } } }

代碼測試:

    //測試代碼
        public static void main(String[] args) {
        MergesSort ms=new MergesSort();
        
        int a[]={8,-6,2,-7,9,-23,2,7,4,67,1,8};
        //註意第三個參數是數組的結束坐標,因為數組是從0開始的,所以結束的坐標需要數組的長度-1
        ms.mergeSort(a,0,a.length-1);
        int i=0;
        while(i<a.length){
            System.out.print(a[i++]+"  ");
        }
    }

結果:

技術分享

寫此博客希望以後忘記的時候能夠回顧一下,代碼如果有不對的地方,請大佬們指正,謝謝~

歸並排序:步驟講解與代碼實現