PAT甲级1098 Insertion or Heap Sort 模拟插入和堆排序

7 篇文章 0 订阅
6 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述

题意:

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

思路:

先进行插入排序,如果执行过程中发现与给定序列吻合,则说明是插入排序,如果不吻合,则说明是堆排序。

代码如下:

//模拟插入排序和堆排序
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int n;
vector<int>init;//初始的数组
vector<int>goal;//当前的数组
vector<int>cur;//当前变化中的数组

void max_heapify(int i,int h){//建立一个最大堆
    int l,r,largest;
    l=2*i+1;
    r=2*i+2;

    if(l<=h&&init[l]>init[i]){
        largest=l;
    }else{
        largest=i;
    }
    if(r<=h&&init[r]>init[largest]){
        largest=r;
    }
    if(largest!=i){
        swap(init[i],init[largest]);
        max_heapify(largest,h);
    }
}

int main(){
    cin>>n;
    init.resize(n);
    goal.resize(n);
    cur.resize(n);
    for(int i=0;i<n;i++){
        cin>>init[i];
        cur[i]=init[i];
    }

    for(int i=0;i<n;i++){
        cin>>goal[i];
    }

    bool flag=false;
    for(int i=0;i<n;i++){
        sort(cur.begin(),cur.begin()+i+1);
        if(cur==goal){//若满足插入排序
            flag=true;
        }
    }

    if(flag){//若满足插入排序
        int pos=n-1;
        int cur_num=goal[0];//当前数字
        for(int i=0;i<n;i++){
            if(goal[i]<cur_num){
                pos=i;
                break;
            }
            cur_num=goal[i];
        }
        sort(goal.begin(),goal.begin()+pos+1);
        cout<<"Insertion Sort"<<endl;
        for(int i=0;i<n;i++){
            if(i!=n-1){
                cout<<goal[i]<<" ";
            }else{
                cout<<goal[i];
            }
        }
    }else{//否则就是堆排序
        for(int i=n/2-1;i>=0;i--)
            max_heapify(i,n-1);//建堆,从第一个叶子节点开始
        }

        bool flag1=false;
        for(int i=n-1;i>=1;i--){//堆排序
            swap(init[0],init[i]);
            for(int j=i/2-1;j>=0;j--){
                max_heapify(j,i-1);
            }
            if(flag1==true){
                cout<<"Heap Sort"<<endl;
                for(int j=0;j<n;j++){
                    if(j!=n-1){
                        cout<<init[j]<<" ";
                    }else{
                        cout<<init[j];
                    }
                }
                break;
            }
            if(init==goal){
                flag1=true;
            }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值