經典排序算法(8)——歸併排序算法詳解

歸併排序(Merge sort),是創建在歸併操作上的一種有效的排序算法,效率爲O(nlog n)。該算法是採用分治法(Divide and Conquer)的一個非常典型的應用,且各層分治遞歸可以同時進行。


一、算法基本思想

(1)基本思想

歸併排序的基本思想就是:把待排序序列分爲若干個子序列,每個子序列是有序的,然後再把有序子序列合併爲整體有序序列。經常被使用的是二路歸併算法,即將兩個已經排序的序列合併成一個序列的操作。

(2)運行過程

歸併排序算法的運行過程如下:

1、申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;

2、設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;

3、比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;

4、重複步驟3直到某一指針達到序列尾;

5、將另一序列剩下的所有元素直接複製到合併序列尾。

(3)示例


二、算法實現(核心代碼)

C++實現:

template<typename T> //整數或浮點數皆可使用
void merge_sort(T arr[], int len) {
	T* a = arr;
	T* b = new T[len];
	for (int seg = 1; seg < len; seg += seg) {
		for (int start = 0; start < len; start += seg + seg) {
			int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
			int k = low;
			int start1 = low, end1 = mid;
			int start2 = mid, end2 = high;
			while (start1 < end1 && start2 < end2)
				b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
			while (start1 < end1)
				b[k++] = a[start1++];
			while (start2 < end2)
				b[k++] = a[start2++];
		}
		T* temp = a;
		a = b;
		b = temp;
	}
	if (a != arr) {
		for (int i = 0; i < len; i++)
			b[i] = a[i];
		b = a;
	}
	delete[] b;
}

Java實現:

public void merge_sort(int[] arr) {
    int len = arr.length;
    int[] result = new int[len];
    int block, start;
		
    for(block = 1; block < len ; block *= 2) {
        for(start = 0; start <len; start += 2 * block) {
            int low = start;
            int mid = (start + block) < len ? (start + block) : len;
            int high = (start + 2 * block) < len ? (start + 2 * block) : len;
            //兩個塊的起始下標及結束下標
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;
            //開始對兩個block進行歸併排序
            while (start1 < end1 && start2 < end2) {
	        result[low++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
            }
            while(start1 < end1) {
	        result[low++] = arr[start1++];
            }
            while(start2 < end2) {
	        result[low++] = arr[start2++];
            }
        }
	int[] temp = arr;
	arr = result;
	result = temp;
    }
    result = arr;       
}

三、性能(算法時間、空間複雜度、穩定性)分析

歸併排序的時間複雜度爲O(nlogn)空間複雜度爲O(n);是穩定的排序算法

歸併排序速度僅次於快速排序,爲穩定排序算法。一般用於對總體無序,但是各子項相對有序的數列效果比較好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章