归并算法

8645 归并排序(非递归算法)


要求:

用函数实现归并排序(非递归算法),并输出每趟排序的结果

输入格式

第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式

每行输出每趟排序的结果,数据之间用一个空格分隔

输入样例

10
5 4 8 0 9 3 2 6 7 1

输出样例



4 5 0 8 3 9 2 6 1 7
0 4 5 8 2 3 6 9 1 7
0 2 3 4 5 6 8 9 1 7

0 1 2 3 4 5 6 7 8 9


这是华农的题目,要在华农的系统上提交,里面有一个很坑学生的问题,一会儿会谈到,先看看代码。


#include<stdio.h>
#include<malloc.h>

struct tab
{
	int *r;
	int length;
};

void prinf(tab T)
{
	int i;
	for(i = 1;i <= T.length;i++)
		printf("%d ",T.r[i]);
	printf("\n");
}

void merge(tab &T1,tab &T2,int u,int m,int v)
{
	int i,j,k,t;
	i = u;
	j = m+1;
	k = u;
	while(i <= m&&j <= v)
	{
		if(T1.r[i] < T1.r[j])
		{
			T2.r[k] = T1.r[i];
			i++;
		}
		else
		{
			T2.r[k] = T1.r[j];
			j++;
		}
		k++;
	}
	if(i <= m)
		for(t = i;t <= m;t++)
			T2.r[k+t-i] = T1.r[t];
		else
			for(t = j;t <= v;t++)
				T2.r[k+t-j] = T1.r[t];
}

void mergepass(tab &T1,tab &T2,int len)
{
	int i,j,n;
	n = T2.length = T1.length;
	i = 1;
	while(i <= n - 2 * len + 1)
	{
		merge(T1,T2,i,i + len - 1,i + 2 * len - 1);
		i = i + 2 * len;
	}
	if(i + len - 1 < n)
		merge(T1,T2,i,i+len-1,n);
	else
	{
		for(j = i;j <= n;j++)
			T2.r[j] = T1.r[j];
	}
	for(i = 1;i <= T1.length;i++)
		T1.r[i] = T2.r[i];
	prinf(T1);//★★★★
}


void mergesort(tab &T)
{
	int len;
	tab tem;
	tem.length = (int )malloc(sizeof(int));
	tem.r = (int *)malloc(T.length*sizeof(int));
	len = 1;
	while(len < T.length)
	{
		mergepass(T,tem,len);
		len = 2*len;
//		mergepass(tem,T,len);
//		len = 2*len;
	}
	tem.r = NULL;
}

int main()
{
	int i;
	struct tab T;
	T.length = (int)malloc(sizeof(int));
	scanf("%d",&T.length);
	T.r = (int*)malloc(T.length*sizeof(int));
	for(i = 1;i <= T.length;i++)
	{
		scanf("%d",&T.r[i]);
	}
	mergesort(T);
	return 0;
}

相信来看这个的朋友都已经了解过归并排序,所以一些注释没有也就没所谓了,不难看懂。

那两行注释掉的代码,本来是用来运行的,而注释有“★★★★”的那行,里面的T1本来是T2的,而且这行之前是没有

for(i = 1;i <= T1.length;i++)
		T1.r[i] = T2.r[i];
 


这个的,这个大家应该看得出是用来把数据换回原来的结构里面的。

原来那个版本在一个while循环里面用两次mergepass函数,存储数据的结构体发生交换,所以要用两次。而后来那个版本直接在merge函数那里交换,就免去了后面调用两次mergepass。

两个版本运行输出的结果都一样,可是我没有注释的那个版本提交的时候却报错,而且没有任何说明。

后来我找同学的代码看了一下。就改成了后来那个版本,提交之后就通过了。

我觉得应该是这样的,那个系统不仅仅要求输出一致,而且还要输出的数值存放的地址是前后一致的才行。

这绝对坑爹!!我提交了5次错误,第6次才通过。

(另外,这个博客的东西我还不太熟悉,这些代码放出来有点怪怪的,有些看上去明显不属于我本意打出来的东西就不要管啦。)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值