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;
}
相關文章
相關標籤/搜索