二叉树中任意两节点的最低共同父节点

通过两个和二叉树相关的算法题来看看和递归在二叉树中的应用

输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。

思路: 如果这两个节点不在同一个子树下面,那么这棵树的根节点就是他们的共同最低父节点。

如果两个都在右子树,那么以右子树的最上面的那个节点作为根节点,重新进行判断,递归调用。

同理两个都在左子树,则方法同上。  也就是说,最终的结果分别只有三种情况,一个节点在右子树,一个节点在左子树。两个节点都在右子树,两个节点都在左子树。

如果是第一种情况,那么当前的节点就是他们最低的公共节点,左右都在左子树,或者在右子树,那么就递归调用。

BinTree* GetParent(BinTree* root,BinTree* first,BinTree* second)
{
         if(root == NULL)
           return ;
         if(root == first || second == second)
         {
           return root;        
         }
         BinTree* Low_left = GetParent(root->left,first,second);
         BinTree* Low_right = GetParent(root->right,first,second);
         /*说明在左子树中没有找到和first/second中任何一个相同的节点  公共父节点右子树 而且第一个就是*/  
         if(Low_left == NULL)  
           return Low_right;
         /*在右子树中没有找到和first/second中任何一个相同的节点 公共父节点在左子树 而且第一个就是最低父节点*/
         else if(Low_right == NULL)
           return Low_left;
         else
            return root;
 } 
在左子树中没找到任何一个节点,那么就在右子树中找,在右子树中没找到任何一个节点,那么共同父节点肯定在左子树。如果在左右子树中各找到一个节点(注意并不可能同时找到两个节点的),那么当前节点就是最低共同父节点。

递归解法效率很低,有很多重复的遍历,下面看一下非递归解法。
非递归解法:
先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点
参考代码如下:

    bool GetNodePath(BinaryTreeNode * pRoot, BinaryTreeNode * pNode,   
                     list<BinaryTreeNode *> & path)  
    {  
        if(pRoot == pNode)  
        {     
            path.push_back(pRoot);  
            return
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我已经理解了你的问题。下面是C语言的代码实现: ``` #include<stdio.h> //定义二叉树结点的数据结构 struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; //搜索二叉树指定值的结点 struct TreeNode* searchNode(struct TreeNode* root, int val) { if (!root || root->val == val) { return root; } if (val < root->val) { return searchNode(root->left, val); } else { return searchNode(root->right, val); } } //计算个结点的公共祖先 struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { if (!root || root == p || root == q) { return root; } if ((root->val > p->val && root->val < q->val) || (root->val > q->val && root->val < p->val)) { return root; } if (root->val > p->val && root->val > q->val) { return lowestCommonAncestor(root->left, p, q); } else { return lowestCommonAncestor(root->right, p, q); } } int main() { //构建二叉树 struct TreeNode a = {6, NULL, NULL}; struct TreeNode b = {2, NULL, NULL}; struct TreeNode c = {0, NULL, NULL}; struct TreeNode d = {4, NULL, NULL}; struct TreeNode e = {3, NULL, NULL}; struct TreeNode f = {5, NULL, NULL}; struct TreeNode g = {8, NULL, NULL}; struct TreeNode h = {7, NULL, NULL}; struct TreeNode i = {9, NULL, NULL}; a.left = &b; a.right = &g; b.left = &c; b.right = &d; d.left = &e; d.right = &f; g.left = &h; g.right = &i; //读取输入 int node1, node2; scanf("%d", &node1); scanf("%d", &node2); //搜索二叉树指定值的结点 struct TreeNode* p = searchNode(&a, node1); struct TreeNode* q = searchNode(&a, node2); //计算个结点的公共祖先 struct TreeNode* result = lowestCommonAncestor(&a, p, q); //输出结果 printf("%d", result->val); return 0; } ``` 其,我们通过searchNode函数来查找二叉树对应值的结点,然后通过lowestCommonAncestor函数来计算个结点的公共祖先,最后输出结果即可。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值