查找树中两个节点的最低公共祖先

求树中两个节点的最低公共祖先

给定一棵树和两个节点,求解这两个节点在树中的最低公共祖先节点。(剑指Offer)

思路:
从根节点遍历树,直到要查找的节点,保存从根节点到要查找的节点的路径。遍历两次树,即保存了根节点到要查找的两个节点的两条路径,然后求出两条路径的最后一个交点即可。

C++代码实现:

#include <iostream>
#include <vector>
#include <list>

using namespace std;

typedef struct TreeNode{
    int data;
    struct TreeNode *leftChild;
    struct TreeNode *rightChild;
}TreeNode, *BiTree;

bool GetNodePath(TreeNode* pRoot, int data, list<BiTree> &path){
    if(pRoot == NULL){
        return false;
    }
    if(pRoot->data == data){
        return true;
    }

    path.push_back(pRoot);

    bool found = false;

    if(!found){
        found = GetNodePath(pRoot->leftChild, data, path);
    }
    if(!found){
        found = GetNodePath(pRoot->rightChild, data, path);
    }

    if(!found){
        path.pop_back();
    }
    return found;

}

BiTree GetLastCommonNode(list<BiTree> &path1, list<BiTree> &path2){
    list<BiTree>::const_iterator i1 = path1.begin();
    list<BiTree>::const_iterator i2 = path2.begin();

    BiTree pLast = NULL;

    for(;i1!=path1.end() && i2!=path2.end();){
        if(*i1 == *i2){
            pLast = *i1;
        }
        ++i1;
        ++i2;
    }
    return pLast;
}

BiTree GetLastCommonParent(TreeNode* pRoot, int data1, int data2){
    if(pRoot == NULL){
        return NULL;
    }

    list<BiTree> path1, path2;
    GetNodePath(pRoot, data1, path1);

    GetNodePath(pRoot, data2, path2);

    return GetLastCommonNode(path1, path2);
}

int creatTree(BiTree &T){
    int data;
    cin >> data;
    if(data == -1){
        T = NULL;
        return 0;
    }else{
        T = (BiTree)malloc(sizeof(TreeNode));
        T->data = data;
        creatTree(T->leftChild);
        creatTree(T->rightChild);
    }
    return 0;
}


int main(int argc, const char * argv[]) {
    // insert code here...

    BiTree T, result;

    int data1, data2;

    creatTree(T);

    cin >> data1 >> data2;
    result = GetLastCommonParent(T, data1, data2);
    cout << result->data << endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值