二叉树中找两个结点的最近的公共祖先结点

#pragma once
#include <iostream>
using namespace std;

/****************
 * 二叉树中 找两个结点的最近的公共祖先结点
******************/

struct Node
{
    Node* left;
    Node* right;
    int value;

    Node(int v)
        :value(v)
        ,left(NULL)
        ,right(NULL)
    {}
};

// 方法一 int count 计数

int _find_ancestor(Node* root, Node* & ancestor, const Node* a, const Node* b)
{
    if (root == NULL)
    {
        return 0;
    }
    int count = 0;
  

    count += _find_ancestor(root->left, ancestor, a , b);

    if (root == a || root == b)
    {
        count += 1;
    }
    /*if (count == 2)
    {
        ancestor = root;
    }*/

   count += _find_ancestor(root->right, ancestor, a, b);

    if (count == 2)
    {
        ancestor = root ;
        count = 0; // 防止返回 时 上面count的值还是2 导致 ancestor不准确 被覆盖
    }
    
    return count;

}

void test_find_ancestor()
{
   //     1
    //  2   3
    // 4  5
    Node n1(1);
    Node n2(2);
    Node n3(3);
    Node n4(4);
    Node n5(5);

    n1.left = &n2;
    n1.right = &n3;
    n2.left = &n4;
    n2.right = &n5;

    Node* ancestor = NULL;
    // 4 5
   // _find_ancestor(&n1, ancestor,&n4, &n5); 

    // 2 5
   // _find_ancestor(&n1, ancestor,&n2, &n5); 

    // 5 3
     _find_ancestor(&n1, ancestor,&n5, &n3); 
}

// 方法二 bool判别

bool find_ancestor_bool(Node* root, Node* & ancestor, const Node* a, const Node* b)
{
    if (root == NULL)
    {
        return false;
    }
  
    bool  b_left = find_ancestor_bool(root->left, ancestor, a, b);

    bool b_right = find_ancestor_bool(root->right, ancestor, a, b);
    
    
    if (root == a || root == b)
    {
        if (b_left || b_right)
        {
            ancestor = root;
        }

        return true;
    }

    if (b_left && b_right)
    {
        ancestor = root;
    }

    return b_left || b_right;

}

void test_find_ancestor_bool()
{
   //     1
    //  2   3
    // 4  5
    Node n1(1);
    Node n2(2);
    Node n3(3);
    Node n4(4);
    Node n5(5);

    n1.left = &n2;
    n1.right = &n3;
    n2.left = &n4;
    n2.right = &n5;

    Node* ancestor = NULL;
    // 4 5
    //find_ancestor_bool(&n1, ancestor,&n4, &n5); 

    // 2 5
   // find_ancestor_bool(&n1, ancestor,&n2, &n5); 

    // 5 3
    // find_ancestor_bool(&n1, ancestor,&n5, &n3); 
     // 1 5
     find_ancestor_bool(&n1, ancestor,&n1, &n5); 
}

// 方法3 利用栈 数组或 链表 记录 找到结点的 路径  最后 遍历两个 栈(数组或链表) 找到第一次出现比相同的点的前一个 即为公共祖先

// 注意 如果当前不是 返回时 要将当前压栈的 元素弹出 栈用引用传入

// 这里以 vector 为例 方便遍历

#include<vector>

void find_ancestor_vector_R(Node* root, vector<Node*>& va,vector<Node*>& vb, Node* a, Node* b, Node* &ancestor)
{
    if (root == NULL)
    {
        return;
    }

    va.push_back(root);
    vb.push_back(root);

    find_ancestor_vector_R(root->left, va, vb, a, b, ancestor);
    find_ancestor_vector_R(root->right, va, vb, a, b, ancestor);
    
    if (va.back() != a)
    {
        va.pop_back();    
    }

    if (vb.back() != b)
    {
        vb.pop_back();
    }
}

Node* find_ancestor_vector(Node* root, Node* a, Node* b)
{
    vector<Node*> va,vb;
    Node* ancestor = NULL;

    find_ancestor_vector_R(root, va, vb, a, b, ancestor);

    // 找va vb 的分叉点 之前的点 
    int i = 0;
    while (i < va.size() && i < vb.size() && va[i] == vb[i])
    {
        ancestor = va[i];
        i++;
    }

    return ancestor;
}

void  test_find_ancestor_vector()
{
    //     1
    //  2   3
    // 4  5
    Node n1(1);
    Node n2(2);
    Node n3(3);
    Node n4(4);
    Node n5(5);

    n1.left = &n2;
    n1.right = &n3;
    n2.left = &n4;
    n2.right = &n5;

    Node* ancestor = NULL;
    // 4 5
    ancestor = find_ancestor_vector(&n1, &n4, &n5); 

    // 2 5
    ancestor = find_ancestor_vector(&n1, &n2, &n5); 

    // 5 3
    ancestor = find_ancestor_vector(&n1, &n5, &n3); 
     // 1 5
     ancestor = find_ancestor_vector(&n1, &n1, &n5); 
}

时间: 2024-08-06 16:05:49

二叉树中找两个结点的最近的公共祖先结点的相关文章

求解二叉查找树中的最低公共祖先结点

一,问题描述 请构造一棵二叉查找树,并给定两个结点,请找出这两个结点的最低公共祖先结点. 这里假设二叉查找树中的结点的权值存储是整型数字(见代码中的BinaryNode内部类),最低公共祖先结点如下:结点5 和 结点12 的最低公共祖先结点是结点10 二,实现思路 假设给定的两个结点的权值分别为 node1 和 node2 如果根的权值处于 node1 和 node2 之间,则根就是它们的最低公共祖先结点 如果根的权值比 node1 和 node2 都大,则它们的最低公共祖先结点在根的左子树中

019写程序在一棵二叉树中找到两个结点的最近共同祖先(keep it up)

写程序在一棵二叉树中找到两个结点的最近共同祖先. 分两种情况来讨论这个题: 第一种情况结点中没有指向父结点的指针 第二种情况接种有指向父节点的指针 我们先看第一种情况,结点中没有指向父结点的指针. 我们可以采用暴力搜索每一个结点,如果这个结点的子树中 有已知的两个结点,那我们就继续沿着左右子树找,如果左子树 能找到,我们就继续沿着左子树找,如果有子树能找到,我们就 沿着右子树找,不存在两个子树都能够找到. 代码: struct TreeNode {<pre name="code"

求二叉树中任意两个结点的距离

求二叉树中任意两个结点的距离 实现步骤: 计算跟到第一个结点的距离: 计算跟到第二个结点的距离: 计算lca: 计算跟到lca结点的距离: 结果为(1) + (2) - 2 * (4),因为重复计算了两次的从跟到lca结点的距离: 1 class Node(object): def __init__(self, value=0): self.value = value self.left = self.right = None def get_path_length(root, n, path)

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

通过两个和二叉树相关的算法题来看看和递归在二叉树中的应用 输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点. 思路: 如果这两个节点不在同一个子树下面,那么这棵树的根节点就是他们的共同最低父节点. 如果两个都在右子树,那么以右子树的最上面的那个节点作为根节点,重新进行判断,递归调用. 同理两个都在左子树,则方法同上.  也就是说,最终的结果分别只有三种情况,一个节点在右子树,一个节点在左子树.两个节点都在右子树,两个节点都在左子树. 如果是第一种情况,那么当前的节点就是他们最低的公共

python3实现在二叉树中找出和为某一值的所有路径

在二叉树中找出和为某一值的所有路径请写一个程序创建一棵二叉树,并按照一定规则,输出二叉树根节点到叶子节点的路径.规则如下:1.从最顶端的根结点,到最下面的叶子节点,计算路径通过的所有节点的和,如果与设置的某一值的相同,那么输出这条路径上的所有节点.2.从根节点遍历树时,请请按照左到右遍历,即优先访问左子树的节点.二叉树创建规则:从上到下一层一层的,按照从左到右的顺序进行构造输入"10,5,12,4,7"值,构造的树如下:1) 102) 10      /    5 3) 10     

bestcoder#43 1002 在数组中找两个数的和取模的最大值 二分

bestcoder#43 1002 在数组中找两个数的和取模的最大值  二分 pog loves szh II Accepts: 97 Submissions: 834 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description Pog and Szh are playing games. There is a sequence with n number

二叉树中任意两个节点的最近公共祖先节点

1.二叉树是个搜索二叉树 2.二叉树带有指向parent的指针 可转换成两个链表的相交节点 3.普通二叉树 保存从根节点分别到这两个节点的路径到list1和list2中 从list1和list2中找第一个不相等的节点即为最近公共祖先节点 template<class T> BinaryTreeNode<T>*  BinaryTree<T>::lastCommnParent(BinaryTreeNode<T>*& node1, BinaryTreeNo

寻找二叉树中的最低公共祖先结点----LCA(Lowest Common Ancestor )问题(递归)

转自 剑指Offer之 - 树中两个结点的最低公共祖先 题目: 求树中两个节点的最低公共祖先. 思路一: --如果是二叉树,而且是二叉搜索树,那么是可以找到公共节点的. 二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大. 如果当前节点的值比两个结点 的值都大,那么最低的共同的父节点一定是在当前节点的左子树中,于是下一步遍历当前节点的左子节点. 如果当前节点的值比两个结点的值都小,那么最低的共同的父节点一定是在当前节点的右子树中,于是下一步遍历当前节点的右子

输出二叉树中随机两个结点的最小公共父结点

思路:当遇到一个结点是返回1,当左右子树都返回1的时候,即最小公共父节点. //二叉树的数据结构 typedef struct MyStruct { char data; struct MyStruct *leftChild; struct MyStruct *rightChild; }Node, *Tree; //查找方法 int findFirstFather(Tree root, char first, char second,char &destination){ int i, j; i