归并排序的一种实现



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

看到一篇博客讲的蛮好的,动态图很生动,下面是链接:

http://blog.csdn.net/wu_lai_314/article/details/8450933


博主同时还在另外一篇博文中介绍了一种改进算法,不过代码虽然能得到正确结果,但是由于程序逻辑不对,实际排序是通过插入排序法进行排序的,其归并排序算是绕了一圈没有解决问题。其链接如下:

http://blog.csdn.net/wu_lai_314/article/details/8452526


这里是我进行修改后的代码:

#define  M 16
#include<iostream>
#include <time.h>
#include<iomanip>

using namespace std;

void insertSort(int *a, int left, int right){
	int tmp;
	int i, j;
	for (i = left + 1; i <= right; i++){//外层循环是从第二个元素开始的
		if (a[i]<a[i - 1]){
			tmp = a[i];
			j = i - 1;
			do{
				a[j + 1] = a[j--];
			} while (j >= left && tmp < a[j]);
			a[j + 1] = tmp;
		}
	}
}


void improvedMerge(int *a, int left, int mid, int right){
	int s1 = left;//s1,s2 是检测指针,t是存放指针
	int s2 = right;
	int t = left, k;
	int *b = new int[right];

	for (k = left; k <= mid; k++)//正向复制
		b[k] = a[k];

	for (k = mid + 1; k <= right; k++)//反向复制
		b[right + mid + 1 - k] = a[k];
	while (t <= right){//归并过程
		if (b[s1] <= b[s2]) a[t++] = b[s1++];
		else	a[t++] = b[s2--];
	}

}

void doSort(int *a, int left, int right){
	if (left >= right) return;
	if (right - left + 1 < M)
	{
		insertSort(a, left, right);//序列长度小于M时候,进行插入排序,再跳出循环
		return;
	}
	int mid = (left + right) / 2;//从中间划分两个子序列
	doSort(a, left, mid);//从左侧子序列进行递归排序
	doSort(a, mid + 1, right);//从右侧子序列进行递归排序
	improvedMerge(a, left, mid, right);//合并
}




void main(){
	int a[100];
	srand((unsigned int)time(NULL));
	for (int i = 0; i<100; i++)
		a[i] = rand();

	doSort(a, 0, 99);
	for (int i = 0; i<100; i++){
		if (i % 7 == 0 && i != 0)
			cout << endl;
		cout << setw(10) << a[i] << " ";
	}
	cout << endl;
	getchar();


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值