1. 程式人生 > >排序演算法---歸併排序

排序演算法---歸併排序

歸併排序的實現分為遞迴實現與非遞迴(迭代)實現。遞迴實現的歸併排序是演算法設計中分治策略的典型應用,我們將一個大問題分割成小問題分別解決,然後用所有小問題的答案來解決整個大問題。非遞迴(迭代)實現的歸併排序首先進行是兩兩歸併,然後四四歸併,然後是八八歸併,一直下去直到歸併了整個陣列。

歸併排序演算法主要依賴歸併(Merge)操作。歸併操作指的是將兩個已經排序的序列合併成一個序列的操作,歸併操作步驟如下:

  1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列
  2. 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
  3. 比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置
  4. 重複步驟3直到某一指標到達序列尾
  5. 將另一序列剩下的所有元素直接複製到合併序列尾

程式碼如下:

#include<iostream>
using namespace std;

// 分類 -------------- 內部比較排序
// 資料結構 ---------- 陣列
// 最差時間複雜度 ---- O(nlogn)
// 最優時間複雜度 ---- O(nlogn)
// 平均時間複雜度 ---- O(nlogn)
// 所需輔助空間 ------ O(n)
// 穩定性 ------------ 穩定

void Merge(int arr[], int left, int mid, int right)
{
	int len = right - left + 1;
	int *temp = new int[len];
	int i = left;
	int j = mid + 1;
	int index = 0;
	while (i <= mid&&j <= right)
	{
		temp[index++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
	}
	while (i <= mid)
	{
		temp[index++] = arr[i++];
	}
	while (j <= right)
	{
		temp[index++] = arr[j++];
	}
	for (int i = 0; i < len; i++)
	{
		arr[left++] = temp[i];
	}
}

void MergeSort(int arr[], int left, int right)
{
	if (left >= right)
		return;

	int mid = (left + right) / 2;
	MergeSort(arr, left, mid);
	MergeSort(arr, mid + 1, right);
	Merge(arr, left, mid, right);
}


int main()
{
	int arr[] = { 5, 3, 6, 9, 2, 8, 1, 7, 4};
	int n = sizeof(arr) / sizeof(int);
	int left = 0;
	int right = n - 1;
	MergeSort(arr, left, right);
	for (int i = 0; i < n; i++)
	{
		cout << arr[i] << endl;
	}

	return 0;
}