归并排序

归并排序

归并是对于元素的集合,用指定个数的元素排序,然后进行合并排序的一种方式。

我们这里主要是研究的两两合并的方式,也称为二路归并。

下面来看看推导过程:

  设有数组int data[8]={9,1,15,8,7,3,6,4};

     1,此时元组为[{9} {1} {15} {8} {7} {3} {6} {4}],把元素分为2个一组,然后排序则有{1,9} {8,15}{3,7}{4,6}

     2,此时发现元组大于1,则继续2个一组归并,得到{1,8,9,15},{3,4,6,7}

     3,此时元组仍然大于1,则继续2个一组归并,得到{1,3,4,6,7,8,9,15}。此时元组为1,结束归并,得到最终结果。

所以,其实归并排序的过程,就分为2个步骤:单元组内排序,2个单元组合并.

来看代码:

//单个数组内元素排序
void arraySort(int *data,const int length)
{
	int* temp = new int[length];//存放归并后的数据
	int mid=length/2;
	int index1=0;
	int index2=mid;
	int i;
	for (i=0;i<=mid&&index1<length&&index2<length;i++)//
	{

		if (data[index1]<data[index2])//第一个序列元素比第二个序列的元素要小,向前
			temp[i]=data[index1++];
		else if (data[index1>data[index2]])//类似
			temp[i]=data[index2++];

	}

	     //把剩余的元素加在数组里
	if (index1!=mid)
	{
		for (;index1<mid;index1++)
		{
			temp[i++]=data[index1];
		}

	}
	else if (index2!=length)
	{
		for (;index2<length;index2++)
		{
			temp[i++]=data[index2];
		}

	}
	     //数组拷贝
	for (int j=0;j<length;j++)
	{
		data[j]=temp[j];
	}
	delete []temp;
	temp=NULL;

}
//两个数组进行合并
void merge(int *data,int start,int end)
{
	int* temp = new int[end-start+1];
	for (int i=start;i<=end;i++)
	{
		temp[i-start]=data[i];
	}//把需要归并的数组拷贝出来
	arraySort(temp,end-start+1);//排序
	for (int i=start;i<=end;i++)
	{
		data[i]=temp[i-start];//使元素组有序
	}

	delete []temp;
	temp=NULL;
}
//归并排序
void mergeSort(int *data,const int length)
{
	for (int i=2;i<=length;i*=2)//两两归并
	{
		for (int j=i;j<=length;j+=i)//j指在数组中需要归并的元素的位置
		{
			merge(data,j-i,j-1);
		}
	}
}//当然了还可以用递归。。。

上面的代码还可以进行优化,比如把排序和归并放在一起,作为一个函数。但是为了更好的理解过程,故写成如上形式。

优化代码请看:http://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F

 

原文地址:https://www.cnblogs.com/273809717/p/2837539.html