09-排序2 Insert or Merge (25分)C语言

本文探讨了在实现Merge排序算法过程中遇到的问题,特别是关于circu变量的正确理解和更新。指出circu不仅可能是实际已合并序列的长度,还可能是其倍数,这导致了在特定测试点上的错误。文章提供了代码示例,详细解释了如何通过遍历排序点间的关系来正确确定和更新circu,避免了将circu误认为是序列最大值的常见陷阱。
  1. 这个题在判断出来是meger排序的时候,circu不一定是实际已合并的长度,也可能是其倍数。导致了最后一个测试点错误,所以要更新circu。
  2. 更新circu的时候,从2开始试,遍历全部排序点间的关系,有一个是前面一个点大于后面的点,就能说明circu==len。但是还要避免实际的circu是len的倍数。
  3. 。。。。还有merge排序不是很熟练
#include<stdio.h>
int pre[100];
int after[100];
void print(int n) {
   for(int i=0; i<n-1; i++) printf("%d ",after[i]);
   printf("%d",after[n-1]);
}
void merge1(int *a,int *tempa,int l,int r,int rend) {
   int lend=r-1;
   int temp=l;
   int num=rend-l+1;
   while(l<=lend&&r<=rend) {
   	if(a[l]>a[r]) tempa[temp++]=a[r++];
   	else tempa[temp++]=a[l++];
   }
   while(l<=lend) tempa[temp++]=a[l++];
   while(r<=rend) tempa[temp++]=a[r++];
   for(int i=num; i>0; i--,rend--) {
   	a[rend]=tempa[rend];
   }
}
void merge(int *a,int n,int circu) {
   int tempa[n];
   int i;
   for( i=0;i<=n-2*circu;i+=2*circu) 
   merge1(a,tempa,i,i+circu,2*circu-1+i);
   if(n-i+1>circu) merge1(a,tempa,i,i+circu,n-1);
   print(n);
}
int getcircu(int n){//circu的值不一定是升序序列的最大值,可能是已排序的merge的倍数 
   int flag=1,len;
   for( len=2;flag;len*=2){
   	for(int j=len;j<n;j+=2*len){//还有这里要*2,否则当len是2时,实际的4可能也会满足 
   		if(after[j-1]>after[j]){
   			flag=0;
   			break;
   		}
   	}
   }
return len/2;
}
bool judge(int n) {
   int circu=1;
   for(;after[circu]>=after[circu-1]&&circu<n;circu++); 
   
   for(int i=circu; i<n; i++) {
   	if(pre[i]!=after[i]) {
   		printf("Merge Sort\n");
   		circu=getcircu(n);
   		 merge(after,n,circu);
   		return 1;
   	}
   }
   printf("Insertion Sort\n");


   for(int i=circu; i<=circu; i++) {
   	int temp=after[i],j;
   	for( j=i; j>0&&after[j-1]>temp; j--) {
   		after[j]=after[j-1];
   	}
   	after[j]=temp;
   }
   print(n);
   return 0;//表示insert
}
int main() {
   int n;
   scanf("%d",&n);
   for(int i=0; i<n; i++) scanf("%d",&pre[i]);
   for(int i=0; i<n; i++) scanf("%d",&after[i]);
   judge(n);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值