编程之美 - 求二叉树节点的最大距离

问题描述:

把在二叉树中,从一个节点到另一个节点的需要经过的边数,定义为距离。

求一棵二叉树中,距离最远的两个节点之间的距离是多少?



问题分析:

最远的节点可能出现两种情况:

1)  位于根节点下面两棵不同的子树上,例如节点C和D

pic_01

2)  位于根节点下面同一棵子树上,例如节点 F 和 I,他们位于B子树上。

pic_02

这样问题可以转化为求二叉树子树上的最远节点,根节点也可以看做是一棵特殊的子树。

1)  一个节点除了保存左右子树的指针外,还分别保存它左右子树中节点的最大的距离。

2)  如果是叶子节点,那么它左右子树的节点的最大距离都是 0。

3)  通过深度优先遍历,由叶子节点逐层向上计算距离,并更新子树的根节点的最大的左右子树的距离。

4)  同时使用全局变量保存最大距离的值。

5)  当深度变量完成后,可以得到整个树中最远的两个节点的距离。


一种动态规划的想法。


代码:

#include <iostream>

using namespace std;

typedef struct _node
{
    int _max_left;
    int _max_right;
    int _data;
    _node *_left;
    _node *_right;

} node;

int nMax = 0;

void calc(node* pNode)
{
    int nTmp = 0;
    if (NULL == pNode)
        return;

    if (NULL == pNode->_left)
    {
        pNode->_max_left = 0;
    }
    else
    {
        calc(pNode->_left);
    }

    if (NULL == pNode->_right)
    {
        pNode->_max_right = 0;
    }
    else
    {
        calc(pNode->_right);
    }

    if (pNode->_left != NULL)
    {
        if (pNode->_left->_max_left > pNode->_left->_max_right)
        {
            pNode->_max_left = pNode->_left->_max_left+1;
        }
        else
        {
            pNode->_max_left = pNode->_left->_max_right+1;
        }
    }

    if (pNode->_right != NULL)
    {
        if (pNode->_right->_max_left > pNode->_right->_max_right)
        {
            pNode->_max_right = pNode->_right->_max_left+1;
        }
        else
        {
            pNode->_max_right = pNode->_right->_max_right+1;
        }
    }

    nTmp = pNode->_max_right + pNode->_max_left;
    if (nTmp > nMax)
    {
        nMax = nTmp;
    }
}

void construct_test1(node* &pRoot)
{
    node* pNode = NULL;
    node* pCurr = NULL;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;

    pRoot = pNode;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pRoot->_left = pNode;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pRoot->_right = pNode;

    pCurr = pRoot->_left;
    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pCurr->_left = pNode;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pCurr->_right = pNode;

    pCurr = pCurr->_left;
    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pCurr->_left = pNode;

    pCurr = pRoot->_right;
    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pCurr->_right = pNode;
}

void construct_test2(node* &pRoot)
{
    node* pNode = NULL;
    node* pCurr = NULL;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;

    pRoot = pNode;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pRoot->_left = pNode;

    pNode = new node;
    pNode->_max_left = 0;
    pNode->_max_right = 0;
    pNode->_max = 0;
    pNode->_left = NULL;
    pNode->_right = NULL;
    pRoot->_right = pNode;

}

int main()
{
    int i = 0;
    node* pRoot = NULL;

    construct_test1(pRoot);
    calc(pRoot);
    cout << "Test 1 : Max length: " << nMax << endl;

    nMax = 0;
    construct_test2(pRoot);
    calc(pRoot);
    cout << "Test 2 : Max length: " << nMax << endl;

    cin >> i;
    return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章