归并排序方法

任意给出一行随机数,对这些随机数从小到大,进行归并排序。

这里只是简单的没有用到递归,后续的改进算法思想:1、不回写(减少这里copy()函数),2、不逆序,(组合片段时,选择那些已经是顺序的片段,例如(3,5,6),(4),(2),(7,8)),3、与插入结合(因为可以证明,当每个片段的长度<=16时,插入排序较好,所以可以选择片度小于16的进行插入排序,然后进行归并)。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define LEN 37

void merge(int i, int j, int d);
void print(int a[]);
void copy();

int a[LEN];
int b[LEN];

void main(void)
{
	int i,j,d;

	srand((unsigned int)time(NULL));
	for(i=0; i<LEN; i++)
	{
		a[i]=rand()%LEN+1;
	}
	printf("排序之前的序列:\n");
	print(a);
	printf("\n");
	//归并的基本思想:把一个长序列,先一个数占一个片段,然后两两按序合并,合并的有序的片段再与其它
	//合并的有序片段进行合并,直到整个序列都是有序的,
	//用i表示第一个片段的起始位置,用j表示第二个片段的起始位置,
	//d表示两个片段之间的跨度,进行两两合并
	
	d=1;
	
	while(d<LEN)
	{
		i=0;
		j=i+d;

		while(j<LEN+1)
		{
			
			merge(i,j,d);
			
			//定位下一对片段位置
			i=i+2*d;    
			j=j+2*d;
		}
		d=2*d;  //新的跨度
		copy();
		//printf("\n***a[0]=%d***\n",a[0]);
	}
	printf("排序之后的序列:\n");
	print(b);
	printf("\n");

}

//把两个有序序列合并到一个序列中
void merge(int i, int j, int d)
{
	int k=i;
	int leni=i+d;
	int lenj;
	if(j+d>LEN)
	{
		lenj=LEN;
	}
	else
	{
		lenj=j+d;
	}
	while(i<leni && j<lenj)
	{
		if(a[i]>a[j])
		{
			b[k]=a[j];
			k++;
			j++;
		}
		else
		{
			b[k]=a[i];
			k++;
			i++;
		}
	}
	while(i<leni)
	{
		b[k]=a[i];
		i++;
		k++;
	}
	while(j<lenj)
	{
		b[k]=a[j];
		j++;
		k++;
	}
}

void print(int a[])
{
	int i;
	for(i=0; i<LEN; i++)
	{
		printf("%3d\t",a[i]);
	}
}

void copy()
{
	int i;
	for(i=0; i<LEN; i++)
	{
		a[i]=b[i];
	}
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值