1. 程式人生 > >分治算法的完美使用----歸並排序

分治算法的完美使用----歸並排序

分治 數組合並 模式 原址 序列 代碼 思路 數組 mage

歸並排序(Merge Sort)算法完全依照了分治模式
  分解:將 n 個元素分成各含 n/2 個元素的子序列;
  解決:對兩個子序列遞歸地排序;
  合並:合並兩個已排序地子序列以得到排序結果;
和快速排序不同的是
  歸並的劃分比較隨意,快排重點就是劃分
  歸並的重點就是合並,快排不需要合並

代碼:

import java.util.Arrays;

public class MergeSort {

    public static void main(String[] args) {
        int arr[] = new int[10];
        
for(int i=0;i<10;i++){ arr[i] = (int) ((Math.random()+1)*10); } System.out.println("排序前:"+Arrays.toString(arr)); mergeSort(arr, 0, arr.length-1); System.out.println("排序後:"+Arrays.toString(arr)); } /** * 思路:將數組分為左右兩個數組,遞歸調用歸並進行排序 * 分別排序完成後,使用輔助的合並函數將兩個有序的子數組合並成一個整體有序的數組 * 時間復雜度:均:O(nlgn),好:O(nlgn),壞:O(nlgn) * 空間復雜度:需要開辟輔助空間,該輔助空間可以重用,大小為N * 非原址排序 * 穩定性:所有排序都是歸並,在左的永遠在左,在右的永遠在右,穩定
*/ static int[]helper; private static void mergeSort(int[] arr, int p, int r) { if (p<r) { int mid = p + ((r-p)>>1); mergeSort(arr, p, mid); // 對左側排序 mergeSort(arr, mid+1, r); // 對右側排序 merge(arr,p,mid,r); //
合並 } } private static void merge(int[] arr, int p, int mid, int r) { // 下面這行代碼只能在這裏使用,不能在主方法使用。 helper = Arrays.copyOf(arr, arr.length); //開辟的一個輔助空間 並拷貝數據 int left = p; // 左側隊伍的頭部指針,指向待比較的元素 int right = mid + 1; // 右側隊伍的頭部指針,指向待比較的元素 int current = p; // 原數組的指針,指向待填入數據的位置 while(left<=mid&&right<=r){ if (helper[left]<=helper[right]) { arr[current] = helper[left]; current++; left++; }else { arr[current] = helper[right]; current++; right++; } } // 如果輔助數組右側的數據沒有全部填入原數組 那麽不用管 因為原數組數據存在的 // 那麽只需要考慮輔助數組左側的數據沒有全部填入原數組的情況 if (left<=mid) { while(left<=mid){ arr[current] = helper[left]; current++; left++; } } } }

結果:

  技術分享圖片

分治算法的完美使用----歸並排序