PAT_甲级_1155 Heap Paths

题目大意:

给定一颗N个节点的彻底二叉树的层次序列,须要输出该树的全部从根节点到叶子节点的路径(优先访问右子树),而后判断是不是堆,若是不是输出Not Heap,不然输出Max Heap或者Min Heap。算法

算法思路:

使用heap数组存储彻底二叉树的层次遍历,无需作任何建树的操做,由于节点的下标之间天然存在父子关系,因此直接使用先序遍历遍历这课树,而且在访问每个节点的时候使用path数组进行保存,在遇到叶子节点的时候就进行输出,节点访问完毕就回溯,该过程使用$preTraverse$函数来完成。紧接着就是使用$isMaxHeap$和$isMinHeap$变量标记当前彻底二叉树是不是大根堆或者小根堆,初始为true,而后使用引用传值到$isMaxOrMinHeap$中,同时判断是不是大根堆或者小根堆,这里采用负向逻辑,只要有左孩子,左孩子小于根节点的说明不是小根堆,不然说明不是大根堆,右孩子亦然如此。最后根据$isMaxHeap$和$isMinHeap$的值进行相应的输出便可。数组

提交结果:

image.png

AC代码:

#include<cstdio>
#include<vector>

using namespace std;

int N;
int heap[1005];
vector<int> path;

void preTraverse(int root){
    if(rreoot>N) return;
    // 先访问当前节点,由于这样就能够在遇到叶子节点的时候获得一个从根节点到叶子节点的路径
    path.push_back(heap[root]);
    if(2*root>N&&2*root+1>N){
        // 到达叶子节点,输出该路径便可
        for(int i=0;i<path.size();++i){
            printf("%d",path[i]);
            if(i<path.size()-1) printf(" ");
        }
        printf("\n");
    }
    preTraverse(2*root+1);
    preTraverse(2*root);
    path.pop_back();
}

void isMaxOrMinHeap(bool &isMaxHeap,bool &isMinHeap){
    for (int i = 1; i <= N; ++i) {
        if((2*i<=N&&heap[i]<heap[2*i])||(2*i+1<=N&&heap[i]<heap[2*i+1])){
            isMaxHeap = false;
        }
        if((2*i<=N&&heap[i]>heap[2*i])||(2*i+1<=N&&heap[i]>heap[2*i+1])){
            isMinHeap = false;
        }
    }
}

int main(){
    scanf("%d",&N);
    for (int i = 1; i <= N; ++i) {
        scanf("%d",&heap[i]);
    }
    postTraverse(1);
    bool isMaxHeap = true;
    bool isMinHeap = true;
    isMaxOrMinHeap(isMaxHeap,isMinHeap);
    if(isMaxHeap){
        printf("Max Heap");
    } else if(isMinHeap){
        printf("Min Heap");
    } else {
        printf("Not Heap");
    }
    return 0;
}
相关文章
相关标签/搜索