1. 程式人生 > >Java排序演算法(三)--歸併排序(MergeSort)遞迴與非遞迴的實現

Java排序演算法(三)--歸併排序(MergeSort)遞迴與非遞迴的實現

歸併有遞迴和非遞迴兩種。

歸併的思想是:
1.將原陣列首先進行兩個元素為一組的排序,然後合併為四個一組,八個一組,直至合併整個陣列;
2.合併兩個子陣列的時候,需要藉助一個臨時陣列,用來存放當前的歸併後的兩個陣列;
3.將臨時陣列複製回原陣列對應的位置。

非遞迴的程式碼如下:

package mergesort;

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
//歸併排序的非遞迴演算法
public class MergeSort{
    public static void main
(String args[]){ MergeSort mer = new MergeSort(); int[] array = mer.getArray(); System.out.println("OriginalArray:" + Arrays.toString(array)); mer.mergeSort(array); System.out.println("SortedArray:" + Arrays.toString(array)); } public int[] getArray(){ Scanner cin = new
Scanner(System.in); System.out.print("Input the length of Array:"); int length = cin.nextInt(); int[] arr = new int[length]; Random r = new Random(); for(int i = 0; i < length; i++){ arr[i] = r.nextInt(100); } cin.close(); return
arr; } public void mergeSort(int[] a){ int len = 1; while(len < a.length){ for(int i = 0; i < a.length; i += 2*len){ merge(a, i, len); } len *= 2; } } public void merge(int[] a, int i, int len){ int start = i; int len_i = i + len;//歸併的前半部分陣列 int j = i + len; int len_j = j +len;//歸併的後半部分陣列 int[] temp = new int[2*len]; int count = 0; while(i < len_i && j < len_j && j < a.length){ if(a[i] <= a[j]){ temp[count++] = a[i++]; } else{ temp[count++] = a[j++]; } } while(i < len_i && i < a.length){//注意:這裡i也有可能超過陣列長度 temp[count++] = a[i++]; } while(j < len_j && j < a.length){ temp[count++] = a[j++]; } count = 0; while(start < j && start < a.length){ a[start++] = temp[count++]; } } }

遞迴演算法的實現程式碼如下:

package mergesort;

public class MergeSort {
    public static void mergeSort(int[] data,int left,int right){ //left,right均為數字元素下標
        if(left<right){
            int half=(left+right)/2;
            mergeSort(data,left,half);
            mergeSort(data,half+1,right);
            merge(data,left,right);
        }
    }
    public static void merge(int []a,int l,int h){
        int mid=(l+h)/2;
        int i=l;
        int j=mid+1;
        int count=0;
        int temp[]=new int[h-l+1];
        while(i<=mid&&j<=h){
            if(a[i]<a[j]){
                temp[count++]=a[i++];
            }else{
                temp[count++]=a[j++];
            }        
        }
        while(i<=mid){
            temp[count++]=a[i++];
        }
        while(j<=h){
            temp[count++]=a[j++];
        }
        count=0;
        while(l<=h){
            a[l++]=temp[count++];
        }
    }
    public static void printArray(int arr[]){
        for(int k=0;k<arr.length;k++){
            System.out.print(arr[k]+"\t");
        }
    }
    public static int[] getArray(){
//      int[] data={4,2,3,1};
        int[] data={543,23,45,65,76,1,456,7,77,88,3,9};
        return data;
    }

    public static void main(String args[]){
        int[]a=getArray();
        System.out.print("陣列排序前:");
        printArray(a);
        System.out.print("\n");
        mergeSort(a,0,a.length-1);
        System.out.print("歸併排序後:");
        printArray(a);
    }
}

歸併排序的時間複雜度為O(n*log2n),空間複雜度為O(n)

歸併排序是一種穩定的排序方法。