归并排序

1.采用递归

1.打印函数

void Print(int* array, int size)
{
	for (int i = 0; i < size; i++)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

2.排序函数
将一个数组分为两个,进行排序(类似于将两个数组合并成一个数组的方法原理)

void MergeData(int* array, int left, int mid, int right, int* temp)
{
	//先将数组分为两个部分,一个从头开始,一个从中间开始 
	int begin1 = left, end1 = mid;
	int begin2 = mid, end2 = right;
	//index表示temp的下标 
	int index = left;

    //循环将小的放入temp中,然后++ 
	while (begin1 < end1 && begin2 < end2)
	{
		if (array[begin1] <= array[begin2])
			temp[index++] = array[begin1++];
		else
			temp[index++] = array[begin2++];
	}

    //处理还没有排序的数字 
	while (begin1 < end1)
		temp[index++] = array[begin1++];

	while (begin2 < end2)
		temp[index++] = array[begin2++];
}

3.递归
这里判断左右之间有数字的话,那就采用递归的方式排好序左右两部分,然后整体进行一次排序,最后将数字拷回到原来的数组

void _MergeSort(int* array, int left, int right, int* temp)
{
	//采用递归的方式 
	if (right - left > 1)
	{
		int mid = left + ((right - left) >> 1);
		_MergeSort(array, left, mid, temp);
		_MergeSort(array, mid, right, temp);
		MergeData(array, left, mid, right, temp);
		//此处的一定要加上left,因为你排了左边,还有右边,右边的下标得从加上left开始 
		memcpy(array + left, temp + left, (right - left)*sizeof(array[0]));//memcpy拷的是字节
	}
}

4.调用

void MergeSort(int* array, int size)
{
	//先给一个temp辅助空间 
	int* temp = (int*)malloc(sizeof(array[0]) * size);
	//空间检测 
	if (NULL == temp)
	{
		assert(0);
		return;
	}

    //调用函数 
	_MergeSort(array, 0, size, temp);
	free(temp);
}

2.循环方式

这种方法是用gap从大的空间里面划分数据,每次进行一点的排序,然后扩大gap范围,再次进行排序,直至循环结束。

void MergeSortNor(int* array, int size)
{
	//用于控制区间的长度 
	int gap = 1;
	//辅助空间 
	int* temp = (int*)malloc(sizeof(array[0]) * size);
	//检测空间 
	if (NULL == temp)
	{
		assert(0);
		return;
	}

    //gap = 1 ,2 ,4 , 8 ...
    //每次归并的范围也就是原来的两倍 
	while (gap < size)
	{
		//利用gap每次归并的范围 
		for (int i = 0; i < size; i += 2 * gap)
		{
			int left = i;
			int mid = left + gap;
			int right = mid + gap;

            //防止越界,如果left是最后一个或者倒数第二个元素,就进行下列操作 
			if (mid > size)
				mid = size;
			if (right > size)
				right = size;

            //排序 
			MergeData(array, left, mid, right, temp);
		}
		//拷贝元素 
		memcpy(array, temp, size*sizeof(array[0]));
		//定义新范围,扩大为原来得两倍 
		gap <<= 1;
	}
	//释放辅助空间 
	free(temp);
}

3.测试代码

//测试代码 
int main()
{
	int array[] = { 8, 2, 1, 5, 3, 4, 7, 6, 9, 0 };
	Print(array, sizeof(array) / sizeof(array[0]));
	//MergeSort(array, sizeof(array) / sizeof(array[0]));
	MergeSortNor(array, sizeof(array) / sizeof(array[0]));
	Print(array, sizeof(array) / sizeof(array[0]));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值