1. 程式人生 > >二叉樹應用_樹中兩個節點的最低公共祖先

二叉樹應用_樹中兩個節點的最低公共祖先

題目:給定樹中的兩個節點,找出這兩個節點的最低公共祖先。

情況1:當給定的樹為二叉搜尋樹時。
分析:由於二叉搜尋樹是排序過的,位於左子樹的節點都小於根節點,位於右子樹的節點都大於根節點。如果要查詢的兩個節點比根節點大的話,則最低公共祖先在右子樹中;如果要查詢的兩個節點比根節點小的話,則最低公共祖先在左子樹中。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

TreeNode*findlastparent(TreeNode*root,TreeNode*pnode1,TreeNode*pnode2)
{
    if
(root->val>pnode1->val && root->val>pnode2->val) return findlastparent(root->left,pnode1,pnode2); else if(root->val<pnode1->val && root->val<pnode2->val) return findlastparent(root->right,pnode1,pnode2); else return
root; }

情況二:樹為普通的二叉樹
分析:找到分別包含要查詢結點的路徑,並將路徑存在一個向量中,在根據這兩個向量找到第一個公共節點即為公共的祖先。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

bool findpath(TreeNode*root,TreeNode*pnode,vector<TreeNode*>
&path) { if(root==NULL) return false; if(root==pnode) { path.push_back(root); return true; } path.push_back(root); if(findpath(root->left,pnode,path)) return true; if(findpath(root->right,pnode,path)) return true; path.pop_back(); return false; } TreeNode* getcommandnode(vector<TreeNode*>&path1,vector<TreeNode*>&path2) { vector<TreeNode*>::iterator it1=path1.begin(); vector<TreeNode*>::iterator it2=path2.begin(); TreeNode*plast=NULL; while(it1!=path1.end()&&it2!=path2.end()) { if(*it1=*it2) plast=*it1; ++it1; ++it2; } return plast; } TreeNode*findlastparent(TreeNode*root,TreeNode*pnode1,TreeNode*pnode2) { if(root==NULL||pnode1==NULL||pnode2==NULL) return NULL; vector<TreeNode*>path1,path2; findpath(root,pnode1,path1); findpath(root,pnode2,path2); return getcommandnode(path1,path2); }

情況三:當連二叉樹都不是隻是一個普通的樹時。
分析:其實這種情況和情況二類似,只是在尋找路徑時遍歷孩子,不只是左右孩子。

struct TreeNode
{
    int                    m_nValue;
    std::vector<TreeNode *>    m_vChildren;
};

//只是需要更改findpath函式
bool findpath(TreeNode*root,TreeNode*pnode,vector<TreeNode*>&path)
{
    if(root==NULL)
        return false;
    if(root==pnode)
    {
        path.push_back(root);
        return true;
    }
    path.push_back(root);
    bool found=false;
    vector<TreeNode *>::iterator it=root->m_vChildren.begin();
    while(it!=m_vChildren.end()&&!found)
    {
        found=findpath(*it,pnode,path);
        ++it;
    }
    if(!found)
        path.pop_back();
    return found;
}