編程之美 - 求二叉樹節點的最大距離

問題描述:

把在二叉樹中,從一個節點到另一個節點的需要經過的邊數,定義爲距離。

求一棵二叉樹中,距離最遠的兩個節點之間的距離是多少?



問題分析:

最遠的節點可能出現兩種情況:

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





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