归并排序 c代码

唯有的两次面试考察了排序,每次都想写个时间复杂度在O(nlogn)。第一次面试一看到排序想都没想直接开撕快速排序,写到一半快速排序的逻辑忘了,尴尬之余速度整了个冒泡排序替代。第二次面试也有一道排序题,当时想都没想直接开撕归并排序,结果在处理辅助数组的时候把自己给绕晕了,越写越慢,临时整了个冒泡排序替代。( ̄_, ̄ )"。冒泡排序还真是好用,呵呵。平常工作的时候遇到排序问题基本上整个冒泡排序就过去了,最近准备面试刷题复习算法的时候,觉得只会写冒泡排序的水平太low了,深深鄙视。仔细想想,无论是快速排序还是归并排序,不管是逻辑还是代码都是相当简单的,但一到笔试的时候写不上来,归根结底还是平时自己要求不高,没有彻底掌握理解,此外就是没有做好准备就直接笔试。我们接着谈归并排序。

归并排序思想就是把两个有序数组合并成一个数组,基本操作是俩有序数组各设一个起始指针i,j,比较arr[ i ], arr[ j ],小的先插入到辅助数组,然后移动i指针。像这样一步步比较插入移动指针,直到一方到了末尾,这时候把另一端剩余的元素全部插入进去即可。这里可以看到,归并操作是需要额外辅助空间的。当我们得到一个无序的数组的时候,需要使用二分法分割该数组,1分2,2分4,直到分割得到的数组子集元素个数为1,这时候两两比较排序归并,自下往上,最终得到有序数组。过程中使用到了递归,即每当数组元素大于1的时候,调用递归继续分割。这里仅有的难点是辅助数组的处理,因为归并不能直接在原始数组上运算,需要借助额外的数组来帮忙,递归返回的是有序数组。可以在递归程序里使用一个额外数组,归并的数据先放在辅助数组里,返回前在将辅助数组里的数据复制到原始数组即可。

c代码:

void MergeSort(int *arr, int left, int right)
{
	//辅助数组
	int arr2[MAXSIZE] = {0};
	
	int i, j, k;
	
	int mid = (right + left) / 2;

    //只有一个元素则返回
	if (left >= right || !arr)
		return;

	//递归分割	
	MergeSort2(arr, left, mid);
	MergeSort2(arr, mid+1, right);

	//归并处理
	k = i = left;
	j = mid + 1;
	while(i <= mid && j <= right)
	{
		if (arr[i] < arr[j])
			arr2[k++] = arr[i++];
		else
			arr2[k++] = arr[j++];			
	}
	if (i>mid)
		while (j<=right)
			arr2[k++] = arr[j++];
	else 		
		while (i<=mid)
			arr2[k++] = arr[i++];

	//返回有序数据
	for (i = left; i <= right; i++)
		arr[i] = arr2[i];
	return;		
}

参考资料:

1. 数据结构 : C语言版/ 严蔚敏,吴伟民编著

=============================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值