非递归的归并排序

非递归的归并排序

简图

在这里插入图片描述

说明

	讲算法的时候都是递归形式的。这里简单写一个非递归的实现。
	就是2、2归并排序,然后4、4归并排序,直到完成。不用递归分组。
	注意,看网上一些代码实现,把归并条件写成 左边<右边,而不是 左边<=右边或者右边<左边。左边<右边这种写法导致的结果是使稳定排序变成了不稳定排序。

代码

#include <stdio.h>
#include <math.h> 
#define  N 11
int mergeSort(int n,int * arr,int *temp)
{	//非递归方式的归并排序 	
//第一步,循环取分组长度,从2的0次方开始,每次乘2,即1,2,4,8,16...不小于n结束 	
	for  (int groupLen=1;groupLen<n;groupLen=groupLen<<1)	
	{		
		int resCount=0;//临时数组temp的下标。存放每次归并结果放在temp中的位置 		
		int groupCount=ceil(n*1.0/groupLen); //分组个数 ,不足一组也算一组 		
		int mergeCount=groupCount>>1;//归并次数 ,2组归并一次。单组不用归并。 			
		//第二步,循环做两个分组的归并处理。		
		for (int i = 0;i<mergeCount;i++)		
		{		
			int left = (i*groupLen)<<1; //左分组的开始位置 			
			int leftSide=left+groupLen; //左分组的结尾位置。			
			int right=leftSide;  //右分组的开始位置 			
			int rightSide=(n<right+groupLen)?n:right+groupLen; 	//右分组的结尾位置。						
			//归并两个数组。归并操作可以封装一个inline函数而不影响性能。这就是非递归的好处。递归无法inline。 			
			while (left<leftSide&&right<rightSide) 			
			{	//归并: 把两个分组头部较小的一个放入临时数组。					
			if(arr[left]<=arr[right]) //如果用arr[left] < arr[right],则是不稳定排序了。						
				temp[resCount++]=arr[left++];						
			else		temp[resCount++]=arr[right++];				
			}    		
			while (left<leftSide) //左分组剩余部分拷贝到临时数组 					
				temp[resCount++]=arr[left++];			
			while (right<rightSide) //右分组剩余部分拷贝到临时数组 				
				temp[resCount++]=arr[right++];		    
			for (left = i<<1; left < rightSide;left++) //把临时数组的归并结果数据拷贝回原数组。 		        
				arr[left] = temp[left];    	
		}
	}
}
//测试一下。
int main(){	
	int n = N;
	int arr[N]={6,3,6,8,6,4,7,8,9,2,1};
	int temp[N];	
	mergeSort(n,arr,temp);	
	for(int i = 0;i < n;i++)		
		printf("%d,",arr[i]) ;	printf("\b \n");
}

结束。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值