PAT.A1098 Insertion or Heap Sort

返回目录在这里插入图片描述

题意

给出一个初始序列,可以对它使用插入排序或堆排序法进行排序。现在给出一个序列,试判断它是由插入排序还是堆排序产生的,并输出下一步将会产生的序列。

样例(可复制)

10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
//output
Insertion Sort
1 2 3 5 7 8 9 4 6 0
10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9
//output
Merge Sort
1 2 3 8 4 5 7 9 0 6

注意点

  1. 本题与B1035/A1089非常类似,需要直接模拟插入排序和堆排序的每一步过程。拥有同样一个陷阱,初始序列不参与与中间序列的比较
  2. 插入部分代码排序考虑直接用sort
  3. 注意堆排序插入元素从数组最后一个开始,从后往前插入
  4. equal是C++标准库中函数,如果两个序列对应位置上的元素都相等,则返回true
# include<bits/stdc++.h>
using namespace std;
int n,A[105],start[105],target[105];
void down(int index,int n){//堆排序下滤
    int t=A[index];
    while(2*index+1<n){//有儿子结点
        int child=2*index+1;
        if(child+1<n&&A[child]<A[child+1])//找到值比较大的儿子结点
            ++child;
        if(A[child]>t){//如果儿子结点的值大于父亲结点的值
            A[index]=A[child];//儿子结点的值移动到父亲结点
            index=child;
        }else
            break;
    }
    A[index]=t;
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++)scanf("%d",&start[i]);
    for(int i=0;i<n;i++)scanf("%d",&target[i]);
    memcpy(A,start,sizeof(start));//将原始序列拷贝给A数组
    bool f=false;
    for(int i=1;i<n;i++){//进行插入排序
        sort(A,A+i+1);//直接使用sort 
        if(equal(A,A+n,target)){
            f=true;
            printf("Insertion Sort\n");
            sort(A,A+i+2);//直接使用sort 
            break;
        }
    }
    if(!f){//是堆排序
        printf("Heap Sort\n");
        memcpy(A,start,sizeof(start));
        for(int i=n/2;i>=0;i--)//将前一半元素进行下滤
            down(i,n);
        for(int i=n-1;i>0;i--){
            swap(A[i],A[0]);
            down(0,i);
            if(equal(A,A+n,target)){
                swap(A[i-1],A[0]);//进行下一趟排序
                down(0,i-1);//进行下一趟排序
                break;
            }
        }
    }
    for(int i=0;i<n;i++){
    	printf("%d",A[i]);
    	if(i!=n-1) printf(" ");
	} 
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小怪兽会微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值