merge sort

归并排序
算法步骤:
 先对子集排序,再归并。
首先归并是最简单的,
先写归并,把两个有序子集合并
void Merge(vector<int> &src ,vector<int> &des, int low, int mid ,int high)
{
int i = low; //左边的集合开始索引
int j = mid +1; //右边的集合开始索引
int k = low; //最后保存的集合索引
while( (i <= mid )&& ( j <= high))
{
if(src[i] <= src[j])
des[ k++ ] = src[i++];
else
des[ k++ ] = src[j++];
}
//如果左边集合还有剩余
while( i<= mid)
{
des[k++] = src[i++];
}
while( j<= high)
{
des[k++] = src[j++];
}
//把排好序的数据放回原来集合
for(int i = istart; i <= iend ;i ++)
    *(pSrc + i ) = *(pDes + i);

 
那下面的问题是子集如何划分呢。
对下面数据进行排列
由此可见,子表的划分是以下过程
1.设每个子表长为1
2.相邻子表合并,有序表长加倍。
3.循环执行,直至表长。
注意:考虑循环时,会存在两种情况,(1)最后的数据一个集合长度正好,一个集合比较少
 (2)最后的数据就剩一个集合,或者小于
//一次merge过程
void MergePass(vector<int> &src , vector<int> &des ,int len) 
{
int length = src.size();
for(int i = 0 : i < n - 2*len ; i = i + len*2)
{
Merge(src,des,i,i+len-1,i+2*len-1);
}
if( i + len -1 <= n)
Merge(src,des,i,i+len-1,length -1);
else
while(i < n)
des[i] = src[i];
}
// 主函数

void mergesort(vector<int> &src)
{
vector<int> des;
int i = 0;
while( i < src.size())
{
MergePass(src,des,i);
i = i *2;

}
}


很显然这是非递归的方法
那递归应该怎么做呢?
很简单
void MergeSort2(vector<int> &src ,vector<int> &des ,int s ,int t)
{
if( s== t) 
des[s] = src [s];
else
{
int m = (s + t) / 2;
MergeSort2(src,des,s,m);
MergeSort2(src,des,m+1,t);
Merge(des,src,s,m,t); //归并到src中
}
}

}

// MergeSort.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;
void MergeSort(int* pSrc ,int iSize);
void MergeSort1(int* pSrc ,int* pDes ,int iLow,int iHight);
int _tmain(int argc, _TCHAR* argv[])
{
	int a[7] = {1,5,7,2,4,6,9};
	int *b = new int[7];
	MergeSort(a,7);
	MergeSort1(a,b,0,6);
	for(int i = 0 ; i < 7; i++)
		cout<<b[i];
	delete []b;
	return 0;
}
// 归并两个有序的子序列
void Merge(int* pSrc, int* pDes, int istart,int imid ,int iend )
{
	int iLeftIndex  = istart;
	int iRightIndex = imid + 1;
	int idesIndex = istart;
	while( (iLeftIndex <= imid )&&(iRightIndex <= iend))
	{
		if( *(pSrc + iLeftIndex) <= *(pSrc + iRightIndex)  )
		{
			*(pDes + idesIndex) = *(pSrc + iLeftIndex);
			iLeftIndex++;
			idesIndex++;
		}
		else
		{
			*(pDes + idesIndex) = *(pSrc + iRightIndex);
			iRightIndex++;
			idesIndex++;
		}
	}
	//如果左边还有剩余
	while(iLeftIndex <= imid )
	{
		*(pDes + idesIndex) = *(pSrc + iLeftIndex);
		idesIndex ++;
		iLeftIndex++;
	}

	如果右边还有剩余
	while(iRightIndex <= iend)
	{
		*(pDes + idesIndex) = *(pSrc + iRightIndex);
		iRightIndex++;
		idesIndex++;
	}
	//把排好序的数据放回原来集合
	for(int i = istart; i <= iend ;i ++)
		*(pSrc + i ) = *(pDes + i);
}

//一次归并排序
/*
参数 iLen表示子表的长度
参数 iSize表示原数组长度
*/
void MergePass(int* pSrc, int* pDes, int iLen, int iSize)
{
	int i = 0;
	while( i <= iSize - 2*iLen)
	{
		Merge(pSrc,pDes,i,i + iLen -1, i + 2 * iLen -1);
		i = i + 2* iLen;
	}
	//还剩两个子序列且其中一个长度小于 iLen
	if( i + iLen  + 1 <= iSize)
		Merge(pSrc,pDes,i,i + iLen -1, iSize -1);
	else
	//还剩小于等于一个子序列,此次不归并
		while( i < iSize)
		{
			*(pDes + i) = *(pSrc + i);
			i++;
		}	
	
}

//归并主程序
void MergeSort(int* pSrc ,int iSize)
{
	int *pTmp = new int[iSize];
	int i = 1;
	while( i < iSize)
	{
		MergePass(pSrc,pTmp,i,iSize);
		i = i * 2;
	}
	delete []pTmp;
	for(int j = 0; j < iSize ; j++)
	{
		cout<< *(pSrc + j);
	}
	cout<<endl;

}

//递归算法
void MergeSort1(int* pSrc ,int* pDes ,int iLow,int iHight)
{
	if(iLow == iHight) 
	{
		*(pDes + iLow) = *(pSrc + iLow);
		return;
	}
	if(iLow < iHight)
	{
		int imid = (iLow + iHight) / 2;
		MergeSort1(pSrc,pDes,iLow,imid);
		MergeSort1(pSrc,pDes,imid + 1,iHight);
		Merge(pDes,pSrc,iLow,imid,iHight);
		for(int i = iLow ; i< iHight;i++)
			*(pDes + i) = *(pSrc + i);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值