PAT【甲级】1155

题目链接:PAT【甲级】1155
题目简述:按完全二叉树层次遍历的方式,给定一行数字。要求去判断给定的这些数字(也即这个二叉树)是不是个二叉堆,如果是堆是最大堆还是最小堆。

#include<bits/stdc++.h>
using namespace std;

int N, batch = 0;
long long table[1000] = {0};
vector<vector<int>> store(501);
string checkAns[3] = {"Max Heap", "Min Heap", "Not Heap"};
void dfs(int beg, int layer){
    if(beg >= N)
        return;
    bool isHasRChild = false;
    store[batch].push_back(table[beg]);
    if(2 * beg + 2 < N){
        dfs(2 * beg + 2, layer + 1);
        isHasRChild = true;
    }
    if(2 * beg + 1 < N){
        if(isHasRChild){//一定要考虑到这一点,不然有逻辑漏洞
            batch++;
            store[batch].assign(store[batch - 1].begin(), store[batch - 1].begin() + layer);
        }
        dfs(2 * beg + 1, layer + 1);
    }
}

int main(){
    cin >> N;
    for (int i = 0; i < N;i++)
        cin >> table[i];
    dfs(0, 1);
    bool isAllOrder_min = false;
    bool isAllOrder_max = false;
    for (int i = 0; i <= batch;i++){
        int pre = store[i][0], temp;
        cout << store[i][0];
        for (int j = 1; j < store[i].size();j++){
            cout << " " << store[i][j];
            temp = store[i][j];
            if(temp > pre){
                isAllOrder_min = true;
            }
            if(temp < pre){
                isAllOrder_max = true;
            }
            pre = temp;//这行没写,都能过测试点,而且还只有一个没过 
        } 
        cout << endl;
    }
    if(!isAllOrder_max && isAllOrder_min)
        cout << checkAns[1] << endl;
    else if(!isAllOrder_min && isAllOrder_max)
        cout << checkAns[0] << endl;
    else
        cout << checkAns[2] << endl;
    return 0;
}

写这个递归我吐了。我的这个逻辑有点混乱,有点复杂,不过幸好能过,恶心坏我了。
看题目,就是一个二叉树的遍历,这个变形的遍历方式要求我们去记录路径,最后将其输出。因为涉及到二叉树的遍历,很自然想到递归的写法,又由于是完全二叉树,一些下标特性也是可以使用的。所以要往递归方向靠。
当然能够想到这样的最初形式:

 void dfs(int beg){
     if(beg >= N)
         return;
     store[batch].push_back(table[beg]);
     dfs(2 * beg + 2);
     dfs(2 * beg + 1);
 }
  • 记录路径。要去把路径记录下来啊,所以要对batch进行操作,会发现一个路径完成后,会转向左孩子遍历,所以batch增加的操作是在转向左孩子时来判断的。
  • 预先判断能否进行遍历。这样的话是可以避免在叶子节点处,我们因为要转向左兄弟遍历时,而无端使得batch增加的情况。但其实这种情况可以通过下面要说的增加标记来解决。
  • 增加标记。增加标记是因为当父节点只有一个左孩子时,我们因右孩子为空,而转向左孩子时出现batch无故增加的情况。

其他的就是简单的判断而已了。至此,我的想法就结束了。但下面我要说一下我的问题:
对于增加标记来解决batch无故增加的问题,其实并不科学。因为这是一颗完全二叉树,才可以这样写,不然仍然不能够解决。
而且我这个递归写的其实也不怎么好,没有突出利用好回溯这一特性,看过别人的博客后才深深明白这一缺陷,利用好这一点,上面我为之困恼的问题就都没有了,而且代码也能更精简一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值