归并排序

归并排序是一种高效的排序算法,时间复杂度为nlogn,与快排相当,是分治法的一种典型应用。

归并排序的思想是将若干个有序的序列合并为一个有序序列,常用的是二路归并,也就是将两个有序子序列合并为一个序列。

归并排序可用递归完成,第一次排序将序列分成两部分,第二次排序将两序列在分成两部分,如此下去,直到每个子序列只有一个元素,则子序列自然有序,然后合并即可。

归并操作的工作原理如下:

  1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

  2.设定两个指针,最初位置分别为两个已经排序序列的起始位置

  3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

  4.重复步骤3直到某一指针达到序列尾

  5.将另一序列剩下的所有元素直接复制到合并序列尾

c++模板实现代码如下:

#include <iostream>
#include <ctime>
using namespace std;

//合并两个有序数组
template <typename T>
void mergerarray(T a[], int first, int mid, int last, T temp[])
{
	int i = first, j = mid+1;
	int m = mid, n = last;
	int k = 0;
	while (i <= m && j <= n){
		if (a[i] < a[j])
			temp[k++] = a[i++];
		else
			temp[k++] = a[j++];
	}
	while (i <= m)
		temp[k++] = a[i++];
	while (j <= n)
		temp[k++] = a[j++];
	for (i=0; i<k; ++i)
		a[first+i] = temp[i];
}

template <typename T>
void mergersort(T a[], int first, int last, T temp[])
{
	if (first < last){
		int mid = (first+last)/2;
		mergersort(a, first, mid, temp);
		mergersort(a, mid+1, last, temp);
		mergerarray(a, first, mid, last, temp);
	}
}

template <typename T>
void MergerSort(T a[], int n)
{
	int* p = new int[n];
	if (p == NULL)
		return ;
	mergersort(a, 0, n-1, p);
}

template <typename T>
void show(T a[], int n)
{
	for(int i=0; i<n; ++i)
		cout << a[i] << ' ';
	cout << endl;
}


测试代码如下:

int main()
{
	const int N = 100000;
	int a[N];

	for (int i=0; i<N; ++i)
		a[i] = N-i;

	clock_t t1 = clock();//记录排序开始时间
	MergerSort(a, N);
	clock_t t2 = clock();//记录排序结束时间

	//测试对100000个数的排序时间
	cout << "sort time: " << (double)(t2-t1)/CLOCKS_PER_SEC << "s" << endl;

	return 0;
}


运行结果如下:

归并排序_第1张图片

你可能感兴趣的:(归并排序)