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

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;
}

 

posted @ 2014-08-08 10:59  匡子语  阅读(472)  评论(0编辑  收藏  举报