1. 程式人生 > >C++排序演算法之歸併排序

C++排序演算法之歸併排序

程式碼實現如下
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

/*該函式將陣列下標範圍[l1,r1]和[l2,r2]的有序序列合併成一個有序序列*/
void merge(vector<int>& nums, int l1, int r1, int l2, int r2 ) {
	int i = l1;                                               //左半部分起始位置
	int j = l2;                                               //右半部分起始位置
	int n = (r1 - l1 + 1) + (r2 - l2 + 1);                    //要合併的元素個數
	vector<int> temp(n);                                      //輔助陣列
	int k = 0;	                                          //輔助陣列其起始位置
	while (i <= r1&&j <= r2) {                                //挑選兩部分中最小的元素放入輔助陣列中
		if (nums[i] < nums[j])
			temp[k++] = nums[i++];
		else
			temp[k++] = nums[j++];
	}
	//如果還有剩餘,直接放入到輔助陣列中
	while (i <= r1)
		temp[k++] = nums[i++];
	while (j <= r2)
		temp[k++] = nums[j++];
	//更新原始陣列元素
	for (int i = 0; i < n;i++)
	{
		nums[l1 + i] = temp[i];
	}
}

/*二路歸併排序(遞迴實現)*/
void MergeSort(vector<int>& nums,int start, int end) {
	if (start < end) {
		int mid = (start + end) >> 1;				//分割序列
		MergeSort(nums, start, mid);				//對序列左半部分進行規並排序
		MergeSort(nums, mid + 1, end);				//對序列右半部分進行規並排序
		merge(nums, start, mid, mid + 1, end);                  //合併已經有序的兩個序列
	}
}

/*二路歸併排序(迭代實現)*/
void MergeSort1(vector<int>& nums, int start, int end)
{
	int n = nums.size();
	if (start < end) {
		//step為組內元素個數,step/2為左子區間元素個數
		for (int step = 2; step/2 <n; step *= 2) {
			//每step個元素一組,組內前step/2和後step/2個元素進行合併
			for (int i = 0; i < n; i += step) {
				int mid = i + step / 2 - 1;					//左子區間元素個數為step/2
				if(mid+1<n)							//右子區間存在元素個數則合併
					//左子區間為[i,mid],右子區間為[mid+1, min(i+step-1, n-1)]
					merge(nums, i, mid, mid + 1, min(i + step - 1, n-1));
			}
		}
	}
}

int main() {
	vector<int> nums{ 1,4,3,2,5,6,3 };
	MergeSort(nums,0,6);
//	MergeSort1(nums, 0, 6);
	for (auto x : nums)
		cout << x << " ";
	cout << endl;
	return 0;
}