剑指offer-树中两个节点的最低公共祖先

来源:互联网 发布:电子签章软件下载 编辑:程序博客网 时间:2024/05/20 01:35

对于这个问题不同的条件可以有不同的解法

  • 树是二叉树且是二叉搜索树。

    这里写图片描述

BinaryTreeNode *GetLastCommonParent(BinaryTreeNode *pRoot,BinaryTreeNode *pNode1,BinaryTreeNode *pNode2){    if (NULL == pRoot)        return NULL;    if (pRoot->_data > pNode1->_data && pRoot->_data > pNode2->_data) //当前结点的值比两个节点的值都大公共祖先一定在左子树中        return GetLastCommonParent(pRoot->_pLeft, pNode1, pNode2);    else if (pRoot->_data < pNode1->_data && pRoot->_data < pNode2->_data)//前结点的值比两个节点的值都小公共祖先一定在右子树中        return GetLastCommonParent(pRoot->_pRight, pNode1, pNode2);    else //        return pRoot;}
  • 树中的每个结点都有指向父结点的指针
    这里写图片描述
    这样就转换成了求两个链表的第一个公共结点。

  • 普通二叉树(没有父结点指针)
    这里写图片描述
    这里写图片描述
    实现代码

//普通二叉树,没有parent指针 //非递归的解法//1.获取结点所在的路径,将路径保存在链表里bool GetNodePath(BinaryTreeNode *pRoot, BinaryTreeNode *pNode, list<BinaryTreeNode*>&path){    if (NULL == pRoot || NULL == pNode)        return false;    if (pRoot == pNode)        return true;    path.push_back(pRoot);    bool found = false;    found = GetNodePath(pRoot->_pLeft, pNode, path);    if (!found)        found = GetNodePath(pRoot->_pRight, pNode, path);    if (!found)        path.pop_back();    return found;}//2. 寻找两个链表的公共节点BinaryTreeNode *GetCommNode(const list<BinaryTreeNode *>&path1,const list<BinaryTreeNode *> &path2){    list<BinaryTreeNode *>::const_iterator iter1 = path1.begin();    list<BinaryTreeNode *>::const_iterator iter2 = path2.begin();    BinaryTreeNode *pNode = NULL;    while (iter1 != path1.end() && iter2 != path2.end())    {        if (*iter1 == *iter2)            pNode = *iter1;        iter1++;        iter2++;    }    return pNode;}BinaryTreeNode *GetCommParent(BinaryTreeNode *pRoot, BinaryTreeNode * pNode1, BinaryTreeNode *pNode2){    if (NULL == pRoot || NULL == pNode1 || NULL == pNode2)        return NULL;    list<BinaryTreeNode *> path1;    list<BinaryTreeNode *> path2;    BinaryTreeNode *Parent = NULL;    bool ret1 = GetNodePath(pRoot, pNode1, path1);     bool ret2 = GetNodePath(pRoot, pNode2, path2);    if (ret1 && ret2)    {        Parent = GetCommNode(path1, path2);    }    return Parent;}

这里写图片描述
非递归解法:
这里写图片描述

//递归解法bool FindNode(BinaryTreeNode *pRoot, BinaryTreeNode *pNode){    if (NULL == pRoot)//上层调用函数已经进行了判空        return false;    if (pRoot == pNode)        return true;    bool found = false;    found = FindNode(pRoot->_pLeft, pNode);    if (!found)        found = FindNode(pRoot->_pRight, pNode);    return found;}BinaryTreeNode *GetCommonParent1(BinaryTreeNode *pRoot,BinaryTreeNode *pNode1,BinaryTreeNode *pNode2){    if (NULL == pRoot || NULL == pNode1 || NULL == pNode2)        return NULL;    if (FindNode(pRoot, pNode1) && FindNode(pRoot, pNode2))    {        if (FindNode(pRoot->_pLeft, pNode1) && FindNode(pRoot->_pLeft, pNode2))            return GetCommonParent1(pRoot->_pLeft, pNode1, pNode2);        else if (FindNode(pRoot->_pRight, pNode1) && FindNode(pRoot->_pRight, pNode2))            return GetCommonParent1(pRoot->_pRight, pNode1, pNode2);        else             return pRoot;    }    return NULL;}

思路参考自剑指offer,解析摘自剑指offer.

原创粉丝点击