【编程题目】二叉树两个结点的最低共同父结点

75.二叉树两个结点的最低共同父结点(树)
题目:二叉树的结点定义如下:
struct TreeNode
{
int m_nvalue;
TreeNode* m_pLeft;
TreeNode* m_pRight;
};
输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。

思路:修改后序遍历 我的方法需要一个额外的整数n来标定。

开始想用非递归,结果写不出来... 只好用递归了....

/*
75.二叉树两个结点的最低共同父结点(树)
题目:二叉树的结点定义如下:
struct TreeNode
{
int  m_nvalue;
TreeNode*  m_pLeft;
TreeNode*  m_pRight;
};
输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。
*/

//思路:修改后序遍历

#include <iostream>
#include <stdlib.h>
#include <vector>
using namespace std;

typedef struct TreeNode
{
int  m_nvalue;
TreeNode*  m_pLeft;
TreeNode*  m_pRight;
}TreeNode;

void createTree(TreeNode * &T)
{
    int data;
    if(scanf("%d",&data) != 0 && data != 0)
    {
        T = (TreeNode *)malloc(sizeof(TreeNode));
        T->m_nvalue = data;
        T->m_pLeft = NULL;
        T->m_pRight = NULL;
        createTree(T->m_pLeft);
        createTree(T->m_pRight);
    }
    return;
}

TreeNode * findLowestCoParent(TreeNode * T, int N1, int N2, int * n)
{

    if(T == NULL)
    {
        return NULL;
    }
    else
    {
        int a = 0;
        int b = 0;
        TreeNode *A = findLowestCoParent(T->m_pLeft, N1, N2, &a);
        TreeNode *B = findLowestCoParent(T->m_pRight, N1, N2, &b);
        if(T->m_nvalue == N1 || T->m_nvalue == N2)
        {
            (*n)++;
        }
        (*n) += (a + b);
        if(a == 2)
        {
            return A;
        }
        if(b == 2)
        {
            return B;
        }
        if((*n) == 2)
        {
            return T;
        }
    }
}

int main()
{
    TreeNode * T = NULL;
    createTree(T);
    int n = 0;
    TreeNode * ans = findLowestCoParent(T, 8,6, &n);

    printf("%d", ans->m_nvalue);
    return 0;
}

找了找网上的答案,具体思路差不多,但是不需要额外的整数。 不过这类代码默认的是输入的两个结点一定有公共父节点,即输入的数字没有错。我的代码在输入出错的情况下如 root, 2000000会返回NULL, 而这类代码会返回root

来源:http://www.cnblogs.com/venow/archive/2012/08/31/2664969.html

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <ctime>
using namespace std;

struct TreeNode
{
    int m_nValue;
    TreeNode *m_pLeft;
    TreeNode *m_pRight;
};

//假定所创建的二叉树如下图所示
/*
                                          /           3
                                        / \      /
  3    6
                                      / \   \  /   8  9  10 11
                                    /          13
                                          /
*/
void CreateBitree(TreeNode *&pNode, fstream &fin, TreeNode *&pNodeOne, TreeNode *&PNodeTwo)
{
    int dat;
    fin>>dat;
    if(dat == 0)
    {
        pNode = NULL;
    }
    else
    {
        pNode = new TreeNode();
        pNode->m_nValue = dat;
        if (NULL == pNodeOne && !(rand() % 3))
        {
            pNodeOne = pNode;
        }
        if (NULL == PNodeTwo && !(rand() % 5))
        {
            PNodeTwo = pNode;
        }
        CreateBitree(pNode->m_pLeft, fin, pNodeOne, PNodeTwo);
        CreateBitree(pNode->m_pRight, fin, pNodeOne, PNodeTwo);
    }
}

//寻找二叉树两个结点的最低共同父节点
TreeNode *FindFirstCommonParentNode(TreeNode *pRoot, TreeNode *pNodeOne, TreeNode *pNodeTwo)
{
    if (NULL == pRoot)
    {
        return NULL;
    }
    if (pRoot == pNodeOne || pRoot == pNodeTwo)
    {
        return pRoot;
    }
    TreeNode *pLeft = FindFirstCommonParentNode(pRoot->m_pLeft, pNodeOne, pNodeTwo);
    TreeNode *pRight = FindFirstCommonParentNode(pRoot->m_pRight, pNodeOne, pNodeTwo);

    if (NULL == pLeft)       //1、左子树没有找到任何一个结点,则第一个公共父节点必定在右子树,而且找到第一个结点就是最低共同父节点
    {
        return pRight;
    }
    else if (NULL == pRight) //2、右子树没有找到任何一个结点,则第一个公共父节点必定在左子树,而且找到第一个结点就是最低共同父节点
    {
        return pLeft;
    }
    else                     //3、分别在结点的左右子树找到,则此节点必为第一个公共父节点
    {
        return pRoot;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    srand((unsigned)time(NULL));
    fstream fin("tree.txt");
    TreeNode *pRoot = NULL;
    TreeNode *pNodeOne = NULL;
    TreeNode *pNodeTwo = NULL;
    TreeNode *pParent = NULL;
    CreateBitree(pRoot, fin, pNodeOne, pNodeTwo);
    pParent = FindFirstCommonParentNode(pRoot, pNodeOne, pNodeTwo);

    cout<<"第一个结点为:"<<pNodeOne->m_nValue<<endl;
    cout<<"第二个结点为:"<<pNodeTwo->m_nValue<<endl;
    cout<<"首个父结点为:"<<pParent->m_nValue<<endl;

    cout<<endl;
    return 0;
}

【编程题目】二叉树两个结点的最低共同父结点

时间: 2024-08-02 19:33:32

【编程题目】二叉树两个结点的最低共同父结点的相关文章

求解二叉树中两个结点的最低公共父结点

一,问题描述 构建一棵二叉树(不一定是二叉查找树),求出该二叉树中某两个结点的最低公共父结点.借用一张图如下: 结点8 和 结点5 的最低公共父结点为 结点2 二,二叉树的构建 与 求二叉树中第K层结点的个数 文章中的第二点:二叉树构建相同 三,求解最低公共父结点的算法实现 有两种思路,一种是通过中序遍历和后序遍历.由于中序遍历是先左子树中的结点,再访问根,再访问右子树中结点,因此这两个结点的公共父结点一定处于这两个结点之间. 如:中序遍历:8, 4, 9, 2, 5, 1, 6, 3, 7  

二叉树两个结点的最低共同父结点 微信:318175542

入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点. 分析:求数中两个结点的最低共同结点是面试中经常出现的一个问题.这个问题至 少有两个变种. 第一变种是二叉树是一种特殊的二叉树:查找二叉树.也就是树是排序过的,位于 左子树上的结点都比父结点小, 而位于右子树的结点都比父结点大. 我们只需要从根结点开 始和两个结点进行比较. 如果当前结点的值比两个结点都大, 则最低的共同父结点一定在当 前结点的左子树中. 如果当前结点的值比两个结点都小, 则最低的共同父结点一定在当前结 点的右子树中.

二叉树两个结点的最低共同父节点

后序遍历就行. //寻找二叉树两个结点的最低共同父节点 TreeNode *FindFirstCommonParentNode(TreeNode *pRoot, TreeNode *pNodeOne, TreeNode *pNodeTwo) { if (NULL == pRoot) { return NULL; } if (pRoot == pNodeOne || pRoot == pNodeTwo) { return pRoot; } TreeNode *pLeft = FindFirstCo

【转】求二叉树两结点的最近共同父结点

求二叉树两结点的最近共同父结点,在网上看到了一个挺有意思的解法,原文在http://www.cnblogs.com/remlostime/archive/2012/11/26/2788795.html 一般思路是从子节点深度遍历到根节点,然后比较两个路径的分叉点.他用的递归: 1 struct Node 2 { 3 int val; 4 Node *left; 5 Node *right; 6 Node():left(NULL), right(NULL){} 7 }; 8 9 Node *fin

C++算法之 求二叉树两个节点的最低公共节点

方法1:递归方法: (1)如果两个节点分别在根节点的左子树和右子树,则返回根节点 (2)如果两个节点都在左子树,则递归处理左子树:如果两个节点都在右子树,则递归处理右子树 bool FindNode(BTree* pRoot, BTree* pNode) { if (pRoot == NULL || pNode == NULL) { return false; } if (pRoot == pNode) { return true; } bool found = FindNode(pRoot->

求二叉树中两个节点的最低公共父节点

必须通过遍历查找一个节点的祖先集合,然后比较两个节点的祖先集合就可以找到最低的那个.这里采用后序遍历,并传入一个栈记录该节点的祖先节点.在每次访问一个节点时,先把这个节点压入栈,然后判断该节点是不是要查找的那个节点,如果是返回.接着查找它的左子树和右子树,当要查找的节点在它的左右子树中则返回.然后判断该节点与栈顶节点是否相同,是则弹出栈顶元素.这是因为相同就代表了在访问它的左右子树时没有添加新的节点,也就是说要查找的那个节点不在它的左右子树中,则该节点也就是不是要查找的节点的祖先. #inclu

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

思路:当遇到一个结点是返回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

编程题目: 两个队列实现栈(Python)

感觉两个队列实现栈 比 两个栈实现队列 麻烦 1.栈为空:当两个队列都为空的时候,栈为空 2.入栈操作:当队列2为空的时候,将元素入队到队列1:当队列1位空的时候,将元素入队到队列2: 如果队列1 和 队列2 都为空的时候,那就选择入队到队列1. 3.出队操作:当两个队列都为空的时候,引发错误"栈为空": 当队列2位空的时候,如果队列1中只有一个元素,则直接将队列1中的元素出队: 如果队列1不止一个元素的时候,就将队列1的元素出队然后入队到队列2,知道队列1中只有一个元素,然后将队列1

寻找二叉树两个节点的最低公共祖先

从root开始遍历,如果n1和n2中的任一个和root匹配,那么root就是LCA. 如果都不匹配,则分别递归左.右子树,如果有一个 key(n1或n2)出现在左子树,并且另一个key(n1或n2)出现在右子树,则root就是LCA.  如果两个key都出现在左子树,则说明LCA在左子树中,否则在右子树. /* 只用一次遍历解决LCA */ #include <iostream> using namespace std; struct Node { struct Node *left, *ri