数据结构学习第二十六课(归并排序)

本文详细介绍了归并排序的原理和步骤,通过实例展示了如何将两个有序数组合并为一个有序数组。代码中实现了归并排序的递归拆分和合并过程,使用临时内存段进行数据的有序存储,并最终覆盖回原始数组。此外,还提供了排序前后的数组打印,便于理解排序效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序:

两个有序数组合并为一个有序数组

步骤:

1 两个指针分别指向两个有序数组;
2 循环遍历并且比较,符合要求的数据存放到最终的内存段中,并且指针后挪;
3 直到有一个数组存放完毕,循环结束;
4 将没有放完的数组拷贝到最终的内存段中;

1 源文件


#include<stdio.h>
#include<string.h>

//归并排序
void merge_sort(int* arr, int len);

//递归拆分 left:左边一半第一个元素下标,right:右边一半最后一个元素的下标
void split(int* arr, int left, int right);

//合并 left:左边一半第一个元素下标,mid:左边一半最后一个元素下标,right:右边一半最后一个元素的下标
void combine(int* arr, int left, int mid, int right);
void print(int* arr, int len);
int main()
{
	int arr[10] = { 15,32,89,456,133,20,46,57,77,966 };

	printf("before :");
	print(arr, 10);

	merge_sort(arr, 10);

	printf("after :");
	print(arr, 10);
	return 0;
}

void merge_sort(int* arr, int len)
{
	split(arr, 0, len - 1);
}

void split(int* arr, int left, int right)
{
	if(left < right)//保证拆分到只有一个元素就停止
	{
		//算中间值
		//int mid = (right - left) / 2 + left;
		int mid = (left+right)/2;
		//拆分
		split(arr, left, mid);//拆左边
		split(arr, mid + 1, right);//拆右边
		//合并
		combine(arr, left, mid, right);

		print(arr + left, right - left + 1);
	}
}

void combine(int* arr, int left, int mid, int right)
{
	//申请临时内存段
	int len = right - left + 1;
	int* pTemp = new int[len];
	//循环比较并把数据有序放到pTemp
	int l = left;//左边一半
	int r = mid+1;//右边一半
	int k = 0;//pTemp的下标
	while (l <= mid && r <= right)
	{
		if (arr[l] < arr[r])
		{
			pTemp[k++] = arr[l++];
		}
		else
		{
			pTemp[k++] = arr[r++];
		}
	}
	//把剩下的也放到pTemp
#if 1
	while(l<=mid)pTemp[k++] = arr[l++];
	while(r<=right)pTemp[k++] = arr[r++];
#else
	if (l <= mid)//左边没放完
	{
		memcpy(pTemp + k, arr + l, sizeof(int) * (mid - l + 1));
	}
	else//右边还没有放完
	{
		memcpy(pTemp + k, arr + right, sizeof(int) * (right - r + 1));
	}
	k += (right - r + 1);
#endif
	//pTemp覆盖回arr中
	memcpy(arr + left, pTemp, sizeof(int) * len);

	//释放pTemp
	delete[] pTemp;
}

void print(int* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值