歸並排序的細節講解與復雜度分析


1.歸並排序時間復雜度為O(N*logN),額外的空間復雜度O(N)。

2.遞歸行為:一個數組的排序,先將左側部分排好序,然后將右側部分排好序,最后整體利用外排序的方式整體排好。

3.歸並排序:將兩個(或者兩個以上)有序表合並成一個新的有序表,即把待排序的序列分成若干個子序列,在把有序的子序列合並為整體有序的序列。算法思路:歸並排序的中心思想是將兩個已經排好的序列,合並成一個排序的序列

4.遞歸排序舉例

  (1)對於數組:[5,3,6,2,0,1]

  序列可以分為:[5,3,6]和[2,0,1]

  (2)對上面的序列分別進行排序,結果為:

  [3,5,6]和[0,1,2]

  然后將上面的兩個序列合並為一個排好序的序列

  合並的方法是:設置兩個指針,分別指着兩個序列的開始位置,如下所示

  [3,5,6]  [0,1,2]

  /|\    /|\

  (3)開始的時候兩個指針分別指向3和0,這時我們找到一個空數組,將3和0中較小的值復制進這個 數組中,並作為第一個元素。新數組:[0,,,,,,]

  (4)后面數組的指針后移一位,如下所示 

  [3,5,6]  [0,1,2]

  /|\     /|\

  將1和3進行比較,1小於3,於是將1插入新數組:[0,1,.......]

  (5)后面數組的指針后移一位,如下所示 

  [3,5,6]  [0,1,2]

  /|\        /|\

  將2和3進行比較,2小於3,於是將2插入新數組:[0,1,2,.......]

  (6)將剩余的左邊已經有序的數組直接復制進入新數組中去,可以得到新數組:[0,1,2,3,5,6]

  (7)有master公式(遞歸公式):T(n)=2T(n/2)+O(N)  可以得出時間復雜度為:O(N*logN)

5.java代碼如下:

import java.util.Arrays;

public class MergeSort1 {
    public static void main(String[] args) {
        //先生成一個隨機數組發生器
        int testTime = 500000;
        int maxSize =100;
        int maxValue=100;
        boolean succeed = true;
        for (int i = 0 ; i <testTime;i++){
            int[] arr1 = generateRandomArray(maxSize,maxValue);
            int[] arr2 = copyArray(arr1);
            mergeSort(arr1);
            comparator(arr2);   //將數組arr2用自帶的默認排序器進行排序
            if(!isEqual(arr1,arr2)){
                succeed=false;
                printArray(arr1);
                printArray(arr2);
                break;
            }

        }
        System.out.println(succeed?"Nice":"fucking fucked");
        int[] arr = generateRandomArray(maxSize,maxValue);
        printArray(arr);
        mergeSort(arr);
        printArray(arr);
    }
    //test
    public static int[] generateRandomArray(int maxSize,int maxValue){
        int[] arr = new int[(int)((maxSize+1)*Math.random())];  //生成一個0到100維之間隨機大小的數組
        for(int i =0 ; i<arr.length;i++){
            arr[i]=(int)((maxValue+1)*(Math.random()))-(int)((maxValue)*Math.random()); //生成兩個0-100之間隨機大小的整數,然后將兩個整數相減
        }
        return arr;
    }
    //test
    public static int[] copyArray(int[] arr){
        if(arr==null){
            return null;
        }
        int[] res = new int[arr.length];
        for(int i = 0 ;i <arr.length;i++){
            res[i]=arr[i];

        }
        return res;
    }

    //test
    public static void comparator(int[] arr){
        Arrays.sort(arr);
    }
    //test
    public static void printArray(int[] arr){
        if(arr==null){
            return;
        }
        for(int i = 0 ; i<arr.length;i++){
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
    //判斷是否相等
    public static  boolean isEqual(int[] arr1,int[] arr2){
        if((arr1==null&&arr2!=null)||(arr1!=null&&arr2==null)){
            return false;
        }
        if((arr1==null) && (arr2==null)){
            return true;
        }
        if(arr1.length!=arr2.length){
            return false;
        }
        for(int i =0 ; i <arr1.length;i++){
            if(arr1[i]!=arr2[i]){
                return false;
            }

        }
        return true;
    }

    public static void  mergeSort(int[] arr){
        if(arr==null || arr.length<2 ){
            return;
        }
        mergeSort(arr,0,arr.length-1);
    }
    public static void mergeSort(int[] arr,int l, int r){
        if(l==r){
            return;
        }
        int mid = (l+r)/2;
        mergeSort(arr,l,mid);
        mergeSort(arr,mid+1,r);
        merge(arr,l,mid,r);
    }
    public static void merge(int[] arr, int l,int mid , int r) {
        int[] help= new int[r-l+1];
        int i =0 ;
        int p1= l ;
        int p2 = mid+1;
        while (p1<=mid&&p2<=r){
            help[i++] =arr[p1]<arr[p2]?arr[p1++]:arr[p2++];
        }
        while (p1<=mid){
            help[i++]=arr[p1++];
        }
        while (p2<=r){
            help[i++] = arr[p2++];
        }
        for(i = 0 ;i<help.length;i++){
            arr[l+i]=help[i];
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM