PAT-A 1147 Heaps

PAT-A 1147 Heaps

题意:

给定一个完全二叉树序列,判断该完全二叉树是否是是堆(大顶堆或小顶堆),最后输出完全二叉树的后序遍历。

代码:

#include<cstdio>
#include<string>
#include<iostream>
using namespace std;

const int MAX_N = 1010;
int tree[2*MAX_N];//用于存放完全二叉树
int T,n;
//0表示属于大顶堆,1表示属于小顶堆,2表示不属于堆
string type[3] = {"Max Heap","Min Heap","Not Heap"};
int flag;
void judge(int index){
    int lchild = tree[2*index];int rchild = tree[2*index + 1];
    if(flag == 0){
        if((lchild != 0 && lchild >= tree[index]) || (rchild != 0 && rchild >= tree[index])){
            flag = 2;
        }
    }
    else if(flag == 1){
        if((lchild != 0 && lchild <= tree[index]) || (rchild != 0 && rchild <= tree[index])){
            flag = 2;
        }
    }
}

void DFS(int index){
    if(index > n) return;
    if(flag != 2){
        judge(index);
    }
    DFS(2*index);
    DFS(2*index+1);
}

void post_traverse(int index){
    if(index > n){return;}
    post_traverse(index*2);
    post_traverse(index*2+1);
    printf("%d",tree[index]);
    if(index != 1){
        printf(" ");
    }
    else printf("\n");
}

int main(){
    cin>>T>>n;
    while (T--)
    {
        for(int i = 1;i<=n;i++){
            scanf("%d",&tree[i]);
        }
        int minn = 1, maxn = 1;
        for(int i = 2;i<=n;i++){
            if(tree[i] < tree[i/2]){
                minn = 0;
            }   
            if(tree[i] > tree[i/2]){
                maxn = 0;
            }
        }
        if(!minn && ! maxn){
            cout<<"Not Heap"<<endl;
        }
        else if(minn == 0){
            cout<<"Max Heap"<<endl;
        }
        else cout<<"Min Heap"<<endl;
        post_traverse(1);
    }
    system("pause");
    return 0;
}

总结

水题。不过还是拓展了一下自己的思路。就是完全二叉树可以使用for循环来代替递归。编号为index的结点父节点为(int)index/2,子节点为2*index。但是由于子节点很有可能为空,所以我们最好通过子节点来访问父节点,这样可以省去一些特判操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值