PATグレード| 1151バイナリツリーの先行順行きがけの成果LCAにおけるLCA

シーケンス与えられた先行順走査シーケンスに単一のツリーを決定することができます

最初のルートへの先行順走査、トラバーサル決定左右のサブツリーINORDER

ノードとノードbの共通の祖先を確認し、LCAシンプルなアイデア:
1とbは、現在の左と右のサブツリーのルートにある場合は、現在のルートが最も近い祖先である
ルートがまたはbに等しい場合2.は、根に等しく、など、判断力と、AとB、など、またはライン上;ルートは、最新の祖先である
3.左のサブツリーにある場合は、再帰的にその上に左のサブツリーを検索します。発見ここで左のサブツリーのルートとの境界(シーケンスのシーケンスによる最初の列)
4.右のサブツリーに、再帰的に右のサブツリーを検索する場合。

コード1:無拠出の練習、反抗ブログ〜劉を参照

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

vector<int> in, pre;
map<int, int > pos;

//先序遍历第一个遍历到的是根,中序遍历确定左右子树

//lca 递归之美 parms:中序左边界 中序右边界 先序遍历到的根的下标 ab值
void lca(int inl, int inr, int preRoot, int a, int b) {
    if (inl > inr) return;//出错
    int inRoot = pos[pre[preRoot]], aIn = pos[a], bIn = pos[b];//取当前根、左边、右边、位置
    if (aIn < inRoot && bIn < inRoot) lca(inl, inRoot - 1, preRoot + 1, a, b);//如果a和b都在左子树,递归查找左子树。参数变化(参考中序遍历):左子树边界(inl~inRoot),先序遍历到下一个结点也就是preRoot+1
    else if (aIn > inRoot && bIn > inRoot) lca(inRoot + 1, inr, preRoot + 1 + (inRoot - inl), a, b);//如果ab都在右子树,递归查找右子树。参数变化:找到中序右子树的界限preRoot+1~inr,找到右子树的先序遍历的根(当前的preRoot + (中序根-左边界inl) + 1),因为右子树先序遍历总是在最后的,等所有左子树上的结点遍历完了才开始遍历右子树,左子树上结点个数也就是需要加的偏移量
    else if ((aIn < inRoot && bIn > inRoot) || (aIn > inRoot && bIn < inRoot)) printf("LCA of %d and %d is %d.\n", a, b, in[inRoot]);//如果ab一左一右,那么根节点就是他们的最近公共祖先
    else if (aIn == inRoot) 
        printf("%d is an ancestor of %d.\n", a, b);//如果a是根,a就是b的祖先
    else if (bIn == inRoot)
        printf("%d is an ancestor of %d.\n", b, a);//同上
}


int main() {
    int m, n, a, b;
    cin >> m >> n;
    in.resize(n + 1), pre.resize(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> in[i];
        pos[in[i]] = i;//存储中序结点所在位置下标
    }
    for (int i = 1; i <= n; i++) cin >> pre[i];
    for (int i = 0; i < m; i++) {
        cin >> a >> b;
        if (pos[a] == 0 && pos[b] == 0) {
            printf("ERROR: %d and %d are not found.\n", a, b);
        }
        else if (pos[a] == 0 || pos[b] == 0) {
            printf("ERROR: %d is not found.\n", pos[a] == 0 ? a : b);
        }
        else {
            lca(1, n, 1, a, b);
        }
    }
    return 0;
}

コード2:再帰的な成果、LCAをチェック

リストツリーは、LCAは最適化しません
:検索ノードと、最近の共通の祖先のノードb、LCAシンプルなアイデア
とbは、それぞれ、現在のサブツリーのルートの中で最も最近の祖先は約ある場合は、現在のルート1.
ルートが場合2.等しいか、またはBがルートは、最も近い祖先であり、ルートに等しく、分析など、AおよびB線のよう
上記条件が満たされていない3、再帰的に再帰的に右サブツリーを検索、左側のサブツリーを検索。
見るためにクリック

おすすめ

転載: www.cnblogs.com/fisherss/p/11139503.html