天天看點

A1043 Is It a Binary Search Tree (25 分) ——PA, 24/25, 先記錄思路

這道題關鍵在于判斷一棵樹是不是 BST

現在題目給出了樹的先序序列——我們可以知道這棵樹的根,然後題目也給出了 BST 的定義——左子樹 < 根 ≤ 右子樹(BST 鏡像則是 左子樹 ≥ 根 > 右子樹),那麼就可以确定左子樹、根、右子樹,進而确定這棵二叉樹。

是以我們可以通過根和根後續結點确定這棵樹是 BST 還是 BST 鏡像。如果是 BST,那麼後面的子樹也要全是 BST;否則後面的子樹全是 BST 鏡像

是以大概的思路就出來了:

/* 僞碼 */

int tree[maxn];//儲存輸入
bool flag = true;//由于判斷是否滿足 BST 特性需要所有子樹都滿足才真正滿足條件,而周遊涉及遞歸不太好傳回,是以設定個标志位用來判斷
void traversal(目前結點 n, 左子樹起始下标 base, 右子樹結束下标 end) {
    /* 死胡同 */
    if (base == end) {//葉子結點
        n->data = tree[base];
        n->left = n->right = NULL;
        return;
    }

    /* 确定左子樹與右子樹 */
    if (tree[base + 1] < n->data) {//左子樹比根小
        //利用 BST 特性找到 tree[] 中第一個大于等于根的就是左右子樹分界
    } else {
        //同理
    }
    if (l - 1 != r)    flag = false;//如果這個分界不是相差 1, 那就不滿足

    /* 遞歸式 */
    traversal(n->left, base, 分界線 - 1);
    traversal(n->right, 分界線, end);
}      

遺憾的是,最後程式 PA。我在 debug 時發現了一例邏輯錯誤的例子,留着後面再回顧了:

/*
暫時發現了一個邏輯錯誤的例子:
5
2 4 3 5 1
無論是 BST 還是 BST 鏡像最後輸出應該是 "NO" 而目前程式輸出 "YES"

錯誤原因是:
(如果按 BST 來組織)既然 [1] 比 [0] 大,那麼 [1] 後面的結點應該全是右子樹————全比 [0] 大;
(如果按 BST 鏡像來組織)既然 [1] 比 [0] 大,那麼 [1]~[3] 應該是左子樹————但這棵左子樹又不滿足 BST 特性

修改了很久都沒改出來,是以先放着 :-(
*/      

點選擷取完整代碼