习题6.8 递归求LCA到两点路径

在这里插入图片描述
思路:借助后序遍历的思想求解,链式存储递归求解。注意前缀权值在LCA点处扣的次数,如果归在一条路径上要扣一次,否则扣两次。

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

struct BiTree {
    int id;
    BiTree *lson, *rson;
    BiTree ():lson(NULL),rson(NULL), id(0){}
    BiTree (int x):lson(NULL),rson(NULL), id(x){}
    ~BiTree() {
        cout << id << endl;
    }
};

//在二叉树T找A、B(Aid、Bid)结点,Ayes、Byes表示当前是否找到对应的点 length表示根结点到目前的路径长度  
int dfs(BiTree* T, bool& Ayes, bool& Byes, int Aid, int Bid, int length) {
    if (T==NULL || Ayes && Byes) 
        return 0;
    //找到A结点
    if (T->id == Aid) {
        Ayes = true;
        //B结点还未找到
        if (!Byes) {
            int l = dfs(T->lson, Ayes, Byes, Aid, Bid, length+1);
            int r = dfs(T->rson, Ayes, Byes, Aid, Bid, length+1);
            if (Byes) return l+r-length; //B点为A点后代
        }
        return length;
    }
    //找到B结点
    if (T->id == Bid) {
        Byes = true;
        //A结点还未找到
        if (!Ayes) {
            int l = dfs(T->lson, Ayes, Byes, Aid, Bid, length+1);
            int r = dfs(T->rson, Ayes, Byes, Aid, Bid, length+1);
            if (Ayes) return l+r-length; //A点为B点后代
        }
        return length;
    }
    bool flag1 = Ayes|Byes; //true表示:当前点可能是最近公共交点
    int l = dfs(T->lson, Ayes, Byes, Aid, Bid, length+1);
    bool flag2 = Ayes^Byes; //左子树找到一个点
    int r = dfs(T->rson, Ayes, Byes, Aid, Bid, length+1);
    bool flag3 = Ayes&Byes; //右子树也找到一个点
    //A、B都找到了,考虑当前点是否要减去多余的前缀
    if (flag3)
        return l+r-(!flag1 && flag2 ? 2*length : 0); //如果当前结点是公共交点要减去公共前缀
    return l+r; //将权值传给公共交点
}

void _free(BiTree* cur) {
    if (cur == NULL) return ;
    _free(cur->lson);
    _free(cur->rson);
    delete cur;
}

int main() {
    BiTree* T;
    T = new BiTree(1);
    BiTree* cur = T;
    cur->lson = new BiTree(2);
    cur = cur->lson;
    cur->lson = new BiTree(4);
    cur->rson = new BiTree(5);
    cur = cur->rson;
    cur->lson = new BiTree(7);
    cur = cur->lson;
    cur->rson = new BiTree(8);
    cur = T;
    cur->rson = new BiTree(3);
    cur = cur->rson;
    cur->rson = new BiTree(6);
    cur = cur->rson;
    cur->lson = new BiTree(9);
    cur->rson = new BiTree(10);
    // bool flagA = false, flagB = false;
    // cout << dfs(T, flagA, flagB, 4, 5, 0) << endl;
    for (int i = 1; i < 10; i++)
        for (int j = i+1; j <= 10; j++) {
            bool flagA = false, flagB = false;
            cout << i << "-->" << j << " : ";
            cout << dfs(T, flagA, flagB, i, j, 0) << endl;
        }
    cout << endl;
    _free(T);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡同的诗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值