[PAT Class A Heap/Tree Traversal C++] 1147 Heaps (30 points)

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

int M, N;
vector<int> A(1001); 

// 使用DFS遍历树,每次都只判断当前结点u和它的左后孩子符不符合堆的要求
void DFS(int u, int &flag){
    
    
    if(u == 1){
    
     // 初始化第一次
        if(N == 2) {
    
    
            if(A[u] >= A[u*2]) flag = 2;
            else 
            if(A[u] <  A[u*2]) flag = 1;
        } 
        else {
    
    
            if(A[u] >= A[u*2] && A[u] >= A[u*2 + 1]) flag = 2;
            else
            if(A[u] <  A[u*2] && A[u] <  A[u*2 + 1]) flag = 1;
            else                                     flag = 0;
        }

    }
    else {
    
     //然后后面每一次的判断都根据前一次的flag来判断,如果上一次的flag和这一次的要求不一致,说明not heap
        if(u > N) return;
        if(u*2 <= N){
    
     // 不是叶子结点
            if(u*2 + 1 <= N){
    
     // 有左右孩子(有右孩子,那必然有左孩子)
                if(flag == 2 && A[u] >= A[u*2] && A[u] >= A[u*2 + 1]) flag = 2; // 当前结点仍符合大根堆
                else
                if(flag == 1 && A[u] <  A[u*2] && A[u] <  A[u*2 + 1]) flag = 1; // 当前结点仍符合小根堆
                else                                                  flag = 0; // 当前结点既不是大根堆也不是小根堆,那就不是堆
            } else {
    
     // 只有左孩子
                if(flag == 2 && A[u] >= A[u*2]) flag = 2;
                else
                if(flag == 1 && A[u] <  A[u*2]) flag = 1;
                else                            flag = 0;

            }
        } else {
    
     // 是叶子结点
            return;
        }
    }
    if(flag == 0) return; // 当前结点表明该序列不是堆,直接返回。

    DFS(u*2    , flag); // 向左子树递归
    DFS(u*2 + 1, flag); // 向右子树递归
}

int cnt;
void postTraverse(int root){
    
     // 后序遍历
    if(root > N) return;
    postTraverse(root*2);
    postTraverse(root*2 + 1);
    cout << A[root] << (cnt++ == N-1 ? "\n" : " ");
}

int main() {
    
    
    cin >> M >> N;
    for(int i = 0;i < M;++i){
    
    
        for(int j = 1;j <= N;++j)
            cin >> A[j];

        int flag;
        DFS(1, flag);

        if(flag == 2){
    
    
            cout << "Max Heap" << endl; 
        } else
        if(flag == 1){
    
    
            cout << "Min Heap" << endl;
        } else
        if(flag == 0) {
    
    
            cout << "Not Heap" << endl;
        }
        cnt = 0;
        postTraverse(1);
    }

    return 0;
}

Guess you like

Origin blog.csdn.net/MYMarcoreus/article/details/114240333