求两个节点的最近公共祖先节点

来源:互联网 发布:屏保制作软件 编辑:程序博客网 时间:2024/05/29 23:43

解法分三种情况:

1.节点有parent,即是三叉链。若是每个节点都有指向父节点的指针,则问题可以变形成求链表相交节点问题。这时就可以让路径长的节点先走几步,接着同时走,判断两个节点是否相等。

int GetLength(Node *node){if (node == NULL)return 0;int len = 0;while (node){node = node->_parent;len++;}return len;}//求两个节点的最近公共祖先,有指向父节点的指针的情况,转化为求两个链表的交点问题Node *FindCommonAncestor(Node *node1, Node *node2){if (_root == NULL || node1 == NULL || node2 == NULL)return NULL;Node* LongLen = NULL;Node* ShortLen = NULL;//分别求出从两个节点到跟节点的路径int len1 = GetLength(node1);int len2 = GetLength(node2);int temp = abs(len1 - len2); //求出两个路径之差if (len1 > len2){LongLen= node1;ShortLeng = node2;}else{LongLen= node2;ShortLen = node1;}//让路径较长的先走for (int i = 0; i < temp; i++)LongLeng = LongLeng->_parent;//接下来一起向前走,直到找到公共节点停止while (LongLen&& ShortLen && (LongLen->_data != ShortLen->_data)){LongLen = LongLen->_parent;ShortLen = ShortLen->_parent;}//直到找到公共节点if (LongLen->_data == ShortLen->_data)return LongLen;else return NULL;}

2.二叉树是二叉搜索树


 可使用递归算法解决,根据搜索二叉树左子树的所有节点比根节点小,右子树的所有节点比跟节点大的性质,若两个节点都比根结点小,则递归左子树,若都比根结点大,则递归右子树,若两个节点一左一右,就可找出当前节点,此时当前节点是最近公共祖先 。

Node* _FindCommonAncestor(Node *&root,Node *&node1, Node *&node2)    {        if (_root == NULL || node1 == NULL || node2 == NULL)            return ;        //1.两个节都小于根节点,最近公共祖先在左子树中        if ((node1->_data < root->_data) && (node2->_data < root->_data))            _FindCommonAncestor(root->_left, node1, node2);        //2.两个节都大于根节点,最近公共祖先在右子树中        else if ((node1->_data> root->_data) && (node2->_data > root->_data))            _FindCommonAncestor(root->_right, n1, n2);        else //3.一个在左子树,一个在右子树,找到公共祖先root            return root;    }
3.二叉树是普通树
                                                                                                                                                                                                                                                              

      从根节点开始遍历,如果node1和node2中的任一个和root匹配,那么root就是最近公共祖先。 如果都不匹配,则分别递归左、右子树,如果有一个 节点出现在左子树,并且另一个节点出现在右子树,则root就是最近公共祖先.  如果两个节点都出现在左子树,则说明最近公共祖先在左子树中,否则在右子树

BinaryNode* GetLastCommonAncestor(Node *root, Node *node1, Node *node2)  {      if (root == NULL || node1 == NULL || node2 == NULL)          return NULL;        if (node1 == root || node2 == root)          return root;        BinaryNode* Left_Lca = GetLastCommonAncestor(root->_left, node1, node2);      BinaryNode* Right_Lca = GetLastCommonAncestor(root->_right, node1, node2);      if (Left_Lca && Right_Lca)          return root;      if (Left_Lca == NULL)          return Right_Lca;      else          return Left_Lca;  }