归并排序数组实现之递归和非递归方法

参考:http://blog.csdn.net/prstaxy/article/details/8166360

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的,然后再把有序子序列合并为整体有序序列。

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

时间复杂度为O(nlogn),空间复杂度为 O(n),归并排序比较占用内存,但却效率高且是稳定的算法。


下面的代码是递归和非递归的实现。

#include<iostream>
using namespace std;
void printArray(int data[],int size);

void merge(int data[], int low,int mid, int high) //两个有序子序列合并
{
	//子序列1:数组下标low到mid           
	//子序列2:数组下标mid+1到high           
	int *temp=new int[high-low+1];
	
	int i=low, j=mid+1, ti=0; //ti:合并后temp数组的下标
	if(temp==NULL)
	{
		cout<<"内存分配失败"<<endl;
	}

	printf("对下标%d--%d--%d  数字%d--%d排序\n",low,mid,high,data[low],data[high]);
	while(i<=mid && j<=high)
	{
		if(data[i]<data[j])
		{
			cout<<data[i]<<"<"<<data[j]<<endl;
			temp[ti++]=data[i++];
		}
		else
		{
			cout<<data[j]<<"<"<<data[i]<<endl;
			temp[ti++]=data[j++];
		}
	}

	while(i<=mid) //若序列1还有剩余,将剩余元素放入新数组中
		temp[ti++]=data[i++];

	while(j<=high) //若序列2还有剩余,将剩余元素放入新数组中
		temp[ti++]=data[j++];

	for(ti=0;ti<high-low+1;ti++) //将排序后的数组元素,放入原数组中相应的位置
		data[low+ti]=temp[ti];

	delete[] temp;
}

//<span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">递归的合并排序,如果子数组中至多有一个元素,当然是已排好,否则分解</span>
void mergeSort(int data[], int low, int high)  //递归实现归并排序
{
	if(low<high) //不少于2个元素,进行合并
	{
		int mid=(low+high)/2;
		mergeSort(data,low,mid);        //拆分左边子序列
		mergeSort(data,mid+1,high);  //拆分右边子序列
		merge(data,low,mid,high);  //合并
		printArray(data,9);
	}
}

void mergeSort(int data[], int n) //非递归实现排序,基本思想是:两两合并
{
	int step=1;  //步长2的指数增长1,2,4,8,16....
	int i;
	while(step<=n) 
	{
		int low=0;  //每次对整个数组合并前,low=0;从头开始
		printf("step=%d\n",step);
		while(low<=n-1)
		{
			int mid=low+step-1;
			int high=mid+step;
			if(high>=n) //high下标判断
				high=n-1;
			if(mid>high) //mid下标判断
				mid=high;
			merge(data,low,mid,high);
			low=high+1;
		}
		printArray(data,9);
		step=step*2;
	}
}

void printArray(int data[],int size)
{
	int i;
	for(i=0;i<size;i++)
		cout<<data[i]<<" ";
	cout<<endl;
}
int main()
{
	int data[9]={5,3,6,2,1,9,4,8,7};
	cout<<"排序前:"<<endl;
	printArray(data,9);
	cout<<"排序过程:"<<endl;
	mergeSort(data,0,8);  //递归
	//mergeSort(data,9);  //非递归
}

递归结果:


排序前:
5 3 6 2 1 9 4 8 7
排序过程:
对下标0--0--1  数字5--3排序
3<5
3 5 6 2 1 9 4 8 7
对下标0--1--2  数字3--6排序
3<6
5<6
3 5 6 2 1 9 4 8 7
对下标3--3--4  数字2--1排序
1<2
3 5 6 1 2 9 4 8 7
对下标0--2--4  数字3--2排序
1<3
2<3
1 2 3 5 6 9 4 8 7
对下标5--5--6  数字9--4排序
4<9
1 2 3 5 6 4 9 8 7
对下标7--7--8  数字8--7排序
7<8
1 2 3 5 6 4 9 7 8
对下标5--6--8  数字4--8排序
4<7
7<9
8<9
1 2 3 5 6 4 7 8 9
对下标0--4--8  数字1--9排序
1<4
2<4
3<4
4<5
5<7
6<7
1 2 3 4 5 6 7 8 9
请按任意键继续. . .



非递归结果:

排序前:
5 3 6 2 1 9 4 8 7
排序过程:
step=1
对下标0--0--1  数字5--3排序
3<5
对下标2--2--3  数字6--2排序
2<6
对下标4--4--5  数字1--9排序
1<9
对下标6--6--7  数字4--8排序
4<8
对下标8--8--8  数字7--7排序
3 5 2 6 1 9 4 8 7
step=2
对下标0--1--3  数字3--6排序
2<3
3<6
5<6
对下标4--5--7  数字1--8排序
1<4
4<9
8<9
对下标8--8--8  数字7--7排序
2 3 5 6 1 4 8 9 7
step=4
对下标0--3--7  数字2--9排序
1<2
2<4
3<4
4<5
5<8
6<8
对下标8--8--8  数字7--7排序
1 2 3 4 5 6 8 9 7
step=8
对下标0--7--8  数字1--7排序
1<7
2<7
3<7
4<7
5<7
6<7
7<8
1 2 3 4 5 6 7 8 9
请按任意键继续. . .


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值