C++编程练习(15)----“排序算法 之 归并排序“

归并排序

归并排序(Merging Sort)的原理:

假设初始序列含有 n 个记录,则可以看成是 n 个有序的子序列,每个子序列的长度为1,然后两两归并,得到 [n/2] ([ x ] 表示不小于 x 的最小整数)个长度为 2 或 1 的有序子序列;再两两归并,·······,如此重复,直至得到一个长度为 n 的有序序列为止,这种排序方法称为 2 路归并排序


归并排序是一种较占用内存,效率高,稳定的算法。


整个排序过程如下图所示:



算法描述:

归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾


具体代码如下:

1、排序前的一些准备工作,建立合适的排序需要的结构。

/********* 排序用到的结构  头文件sort_struct.h ************/
#include <ctime>
#include <cstdlib>
#define MAXSIZE 100 //要排序数组个数最大值


class SqList{
public:
	int r[MAXSIZE+1];
	int length;
};

/* 交换L中数组r下标为i和j的值 */
void swap(SqList *L, int i, int j)
{
	int temp = L->r[i];
	L->r[i] = L->r[j];
	L->r[j] = temp;
}

/* 显示数组内容 */
void showSqList(SqList *L)
{
	for(int i=1;i<=L->length;i++)
		std::cout<<L->r[i]<<"  ";
	std::cout<<std::endl;
}

/* 为数组随机产生一串数字 */
double random(double start, double end)
{
    return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
void RandomCreat(SqList *L,int len)
{	
	double random(double,double);
    srand(unsigned(time(0)));
	for(int i=1;i<=len;i++)
	{
		L->r[i] = int(random(0,100));
	}
}

2、编写主文件,实现排序与测试。

/********* C++堆排序算法 ************/
#include<iostream>
#include<time.h>
#include<Windows.h>
#include"sort_struct.h"
using namespace std;

/* 将有序的SR[i...m]和SR[m+1...n]归并为有序的TR[1...n] */
void Merge(int SR[],int TR[],int i,int m,int n)
{
	int j,k,l;
	for(j=m+1,k=i;i<=m && j<=n;k++)	//将SR中记录由小到大归并入TR
	{
		if(SR[i]<SR[j])
			TR[k] = SR[i++];
		else
			TR[k] = SR[j++];
	}
	if(i<=m)
	{
		for(l=0;l<=m-i;l++)
			TR[k+l] = SR[i+l];	//将剩余的SR[i...m]复制到TR
	}
	if(j<=n)
	{
		for(l=0;l<=n-j;l++)
			TR[k+l] = SR[j+l];	//将剩余的SR[j...n]复制到TR
	}

}

/* 将SR[]中相邻长度为s的子序列两两归并到TR[] */
void MergePass(int SR[],int TR[],int s,int n)
{
	int i = 1;
	int j;
	while(i<=n-2*s+1)
	{
		Merge(SR,TR,i,i+s-1,i+2*s-1);	//两两归并
		i = i+2*s;
	}
	if(i<n-s+1)		//归并最后两个序列
		Merge(SR,TR,i,i+s-1,n);
	else			//若最后只剩下单个子序列
		for(j=i;j<=n;j++)
			TR[j] = SR[j];
}

/* 对顺序表L作归并非递归排序 */
void MergeSort(SqList *L)
{
	int *TR = new int[L->length+1];	//申请额外空间
	int k = 1;
	while (k<L->length)
	{
		MergePass(L->r,TR,k,L->length);
		k = 2 * k;						//子序列长度加倍
		MergePass(TR,L->r,k,L->length);
		k = 2 * k;						//子序列长度加倍
	}
	delete[] TR;
}

int main()
{
	SqList *L = new SqList;
	L->length = 10;
	RandomCreat(L,L->length);
	cout<<"排序前:";
	showSqList(L);

	MergeSort(L);
	cout<<"归并排序后:";
	showSqList(L);

	return 0;
}


运行结果如下:



 

posted @ 2014-05-09 17:18  Never say Ever  阅读(342)  评论(0编辑  收藏  举报