歸併排序

歸併排序

歸併排序基本思想:java

將原數組從中間分開,分紅兩個子數組,而後繼續將子數組從中間分開,直到把全部子數組分解到只有數組

一個元素,此時分的過程就結束了code

而後開始治,遞歸回退一層,將兩個子數組合併成一個新的有序的數組,而後依次回退與其它子數組合併成blog

新的數組,直到合併成原始數組排序

歸併排序基本思想示意圖1:遞歸

歸併排序基本思想示意圖2:索引

代碼實現

public static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if (left < right) {
            int mid = (left + right) / 2;//中間索引,今後處將數組劃分紅兩份
            //向左遞歸進行分解
            mergeSort(arr, left, mid, temp);
            //向右遞歸進行分解
            mergeSort(arr, mid + 1, right, temp);
            //當分解到只有兩個元素的數組時,就開始排序合併
            merge(arr,left,mid,right,temp);
        }
        //只有一個元素了,就不能合併,則回退一層,再合併
    }


	/**
	 *@param arr   排序的原始數組
     * @param left  A有序數組的起始索引
     * @param mid   中間索引,也就是A數組的最後一個索引
     * @param right B數組的終止索引
     * @param temp  合併的數組
     */
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left;//左邊有序序列的初始索引
        int j = mid + 1;//右邊有序序列的初始索引
        int t = 0;//t指向temp數組的當前索引

        //(一)
        //先把左右兩邊(有序)的數據按規則填充到temp數組
        //直到左右兩邊有一邊遍歷結束
        while (i <= mid && j <= right) {
            //比較兩數組中當前索引的數,哪一個小就加入到temp
            if (arr[i] <= arr[j]) {
                temp[t++] = arr[i++];
            } else {
                temp[t++] = arr[j++];
            }
        }

        //(二)
        //將沒有遍歷完的數組的剩餘元素依次所有填充到temp數組
        //由於若是當前數組還有剩餘,就說明另一個數組已經遍歷完成了
        while (j <= right) {
            temp[t++] = arr[j++];
        }

        while (i <= mid) {
            temp[t++] = arr[i++];
        }


        t = 0;
        //(三)
        //將temp數組的元素拷貝到arr
        //第一次合併是 left=0,right=1  left=2,right=3
        //第二次合併是 left=0,right=3
        //最後合併是 left=0,right=7
        for (int k = left; k <= right; k++) {
            arr[k] = temp[t++];
        }
    }
相關文章
相關標籤/搜索