日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

二叉树分析(两点最大距离)

發(fā)布時(shí)間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树分析(两点最大距离) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自:http://blog.csdn.net/lalor/article/details/7626678 ? ? ? ? ??http://blog.csdn.net/lalor/article/details/7618120

把二叉樹(shù)看成一個(gè)圖,父子節(jié)點(diǎn)之間的連線看成是雙向的,我們姑且定義"距離"為兩節(jié)點(diǎn)之間邊的個(gè)數(shù)。寫(xiě)一個(gè)程序求一棵二叉樹(shù)中相距最遠(yuǎn)的兩個(gè)節(jié)點(diǎn)之間的距離。

書(shū)上的解法

書(shū)中對(duì)這個(gè)問(wèn)題的分析是很清楚的,我嘗試用自己的方式簡(jiǎn)短覆述。

計(jì)算一個(gè)二叉樹(shù)的最大距離有兩個(gè)情況:

  • 情況A: 路徑經(jīng)過(guò)左子樹(shù)的最深節(jié)點(diǎn),通過(guò)根節(jié)點(diǎn),再到右子樹(shù)的最深節(jié)點(diǎn)。
  • 情況B: 路徑不穿過(guò)根節(jié)點(diǎn),而是左子樹(shù)或右子樹(shù)的最大距離路徑,取其大者。

只需要計(jì)算這兩個(gè)情況的路徑距離,并取其大者,就是該二叉樹(shù)的最大距離。

代碼參考編程之美,或者h(yuǎn)ttp://www.cnblogs.com/miloyip/archive/2010/02/25/1673114.html

這段代碼有幾個(gè)缺點(diǎn):

  • 算法加入了侵入式(intrusive)的資料nMaxLeft, nMaxRight
  • 使用了全局變量 nMaxLen。每次使用要額外初始化。而且就算是不同的獨(dú)立資料,也不能在多個(gè)線程使用這個(gè)函數(shù)
  • 邏輯比較復(fù)雜,也有許多 NULL 相關(guān)的條件測(cè)試。
  • 我的思路:
    在看到這題的時(shí)候,我沒(méi)有馬上看答案,而是自己思考了一會(huì),得出如下思路,最后跟http://www.cnblogs.com/miloyip/archive/2010/02/25/1673114.html的思路基本一樣,只是實(shí)現(xiàn)上略有不同。

    這個(gè)問(wèn)題的核心是,情況A?及 B 需要不同的信息: A 需要子樹(shù)的最大深度,B 需要子樹(shù)的最大距離。只要函數(shù)能在一個(gè)節(jié)點(diǎn)同時(shí)計(jì)算及傳回這兩個(gè)信息,我是通過(guò)一個(gè)整形指針保存樹(shù)中的局部最大距離。然后通過(guò)返回值,分別樹(shù)的最大深度,如果左右子樹(shù)的最大深度相加大于當(dāng)前樹(shù)的最大距離,則更新最大距離,最后返回左右子樹(shù)中較大的深度,這樣可以輕易求得它們父親的最大深度。(關(guān)于建樹(shù)部分,可以參考http://blog.csdn.net/lalor/article/details/7618120)


    代碼核心:

    int DistanceCore(BinaryTreeNode *root, int *max)
    {
    //如果節(jié)點(diǎn)是葉子節(jié)點(diǎn),則返回0——深度
    if (root->m_pLeft == NULL && root->m_pRight == NULL)?
    {
    return 0;
    }

    //保存左右子樹(shù)的最大深度
    int lDistance = 0;
    int rDistance = 0;

    //左子樹(shù)不為空,返回當(dāng)前節(jié)點(diǎn)到左子樹(shù)的最大深度
    if (root->m_pLeft != NULL)?
    {
    lDistance = 1 + DistanceCore(root->m_pLeft, max);
    }

    if (root->m_pRight != NULL)?
    {
    rDistance = 1 + DistanceCore(root->m_pRight, max);
    }

    //遍歷到當(dāng)前節(jié)點(diǎn)時(shí),能獲得的最大距離
    if (lDistance + rDistance > *max)?
    {
    //保存當(dāng)前獲得的最大距離
    *max = lDistance + rDistance;
    }
    //返回左右子樹(shù)中,深度較大的一個(gè)
    return lDistance > rDistance ? lDistance : rDistance;
    }



    完整代碼如下:

  • #include?<iostream>??
  • #include?<stdlib.h>??
  • using?namespace?std;??
  • ??
  • struct?BinaryTreeNode???
  • {??
  • ????int?m_nValue;??
  • ????struct?BinaryTreeNode?*m_pLeft;??
  • ????struct?BinaryTreeNode?*m_pRight;??
  • };??
  • ??
  • int?maxDistance(BinaryTreeNode?*root,?int?*max);??
  • int?DistanceCore(BinaryTreeNode?*root,int?*max);??
  • //后序遍歷,用于我們建立的二叉樹(shù)是否正確??
  • void?Traverse(?BinaryTreeNode?*?root);??
  • BinaryTreeNode*?Construct(int?*preorder,?int?*inorder,?int?lenght);??
  • BinaryTreeNode*?ConstructCore(int?*startPreorder,?int?*endPreorder,?int?*startInorder,?int?*endInorder);??
  • int?InsertNodeAtMostRight(BinaryTreeNode?*?root,?BinaryTreeNode?*?node);??
  • ??
  • ??
  • int?main(int?argc,?char*?argv[])??
  • {??
  • ??
  • ????int?preOrder[]?=?{5,?4,?8,?9,?6,?3,?18,?19,?2};??
  • ????int?inOrder[]?=?{9,?8,?6,?3,?4,?5,?19,?18,?2};??
  • ??
  • ????int?max;??
  • ??
  • ????//建樹(shù)??
  • ????BinaryTreeNode?*parent?=?Construct(preOrder,?inOrder,?sizeof(inOrder)?/?sizeof(inOrder[0]));??
  • ??
  • ????cout?<<?"A樹(shù)的后序遍歷的結(jié)果:"?<<?endl;??
  • ????Traverse(parent);??
  • ????cout?<<?endl;??
  • ??
  • ????BinaryTreeNode?*node1?=?(BinaryTreeNode?*)malloc(sizeof(BinaryTreeNode));??
  • ????BinaryTreeNode?*node2?=?(BinaryTreeNode?*)malloc(sizeof(BinaryTreeNode));??
  • ??
  • ????node1->m_nValue?=?0;??
  • ????node1->m_pLeft?=?NULL;??
  • ????node1->m_pRight?=?NULL;??
  • ??
  • ????node2->m_nValue?=?0;??
  • ????node2->m_pLeft?=?NULL;??
  • ????node2->m_pRight?=?NULL;??
  • ??
  • ????maxDistance(parent,?&max);??
  • ????cout?<<"max?distance?of?tree's?nodes?:?"?<<?max?<<?endl;??
  • ??
  • ????InsertNodeAtMostRight(parent,?node1);??
  • ????maxDistance(parent,?&max);??
  • ????cout?<<"max?distance?of?tree's?nodes?after?insert?node1:?"?<<?max?<<?endl;??
  • ??
  • ????InsertNodeAtMostRight(parent,?node2);??
  • ????maxDistance(parent,?&max);??
  • ????cout?<<"max?distance?of?tree's?nodes?after?insert?node2:?"?<<?max?<<?endl;??
  • ??
  • ????//測(cè)試極端情況,即只有一個(gè)節(jié)點(diǎn)??
  • ????maxDistance(node2,?&max);??
  • ????cout?<<"just?one?node?"?<<?max?<<?endl;??
  • ??
  • ????//測(cè)試極端情況,即只有二個(gè)節(jié)點(diǎn)??
  • ????maxDistance(node1,?&max);??
  • ????cout?<<"just?two?node?"?<<?max?<<?endl;??
  • ????return?0;??
  • }??
  • ??
  • BinaryTreeNode*?Construct(int?*preorder,?int?*inorder,?int?lenght)??
  • {??
  • ????if?(preorder?==?NULL?||?inorder?==?NULL?||?lenght?<=?0)???
  • ????{??
  • ????????return?NULL;??
  • ????}??
  • ????return?ConstructCore(preorder,?preorder?+?lenght?-?1,?inorder,?inorder?+?lenght?-?1);??
  • }??
  • ??
  • BinaryTreeNode*?ConstructCore(int?*startPreorder,?int?*endPreorder,?int?*startInorder,?int?*endInorder)??
  • {??
  • ????int?rootValue?=?startPreorder[0];??
  • ????BinaryTreeNode?*root?=?new?BinaryTreeNode();??
  • ????root->m_nValue?=?rootValue;??
  • ????root->m_pLeft?=?root->m_pRight?=?NULL;??
  • ??
  • ????if?(startPreorder?==?endPreorder)???
  • ????{//先序遍歷已經(jīng)結(jié)束了,那這個(gè)時(shí)候一定是插入最后一個(gè)節(jié)點(diǎn),則應(yīng)該滿足下面的if語(yǔ)句,否則輸入的數(shù)據(jù)有誤??
  • ????????if?(startInorder?==?endInorder?&&?*startPreorder?==?*startInorder)???
  • ????????{??
  • ????????????return?root;??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????cout?<<?"Invalid?input"?<<?endl;??
  • ????????????exit(-1);??
  • ????????}??
  • ????}??
  • ??
  • ????int?*rootInorder?=?startInorder;??
  • ????while?(rootInorder?<=?endInorder?&&?*rootInorder?!=?rootValue)???
  • ????{??
  • ????????++rootInorder;??
  • ????}??
  • ????if?(rootInorder?<=?endInorder?&&?*rootInorder?!=?rootValue)???
  • ????{??
  • ????????cout?<<?"Invalid?input"?<<?endl;??
  • ????????exit(-1);??
  • ????}??
  • ??
  • ????int?leftLength?=?rootInorder?-?startInorder;??
  • ????int?*leftPreorderEnd?=?startPreorder?+?leftLength;??
  • ??
  • ????if?(leftLength?>?0)???
  • ????{??
  • ????????root->m_pLeft?=?ConstructCore(startPreorder?+?1,?leftPreorderEnd,?startInorder,?rootInorder?-?1);??
  • ????}??
  • ????if?(leftLength?<?endPreorder?-?startPreorder)???
  • ????{??
  • ????????root->m_pRight?=?ConstructCore(leftPreorderEnd?+?1,?endPreorder,?rootInorder?+?1,?endInorder);??
  • ????}??
  • ??
  • ????return?root;??????
  • }??
  • ??
  • void?Traverse(?BinaryTreeNode?*?root)??
  • {??
  • ????if?(root?==?NULL)???
  • ????{??
  • ????????return;??
  • ????}??
  • ????else??
  • ????{??
  • ????????Traverse(root->m_pLeft);??
  • ????????Traverse(root->m_pRight);??
  • ????????cout?<<?root->m_nValue?<<?"??";??
  • ????}??
  • }??
  • int?maxDistance(BinaryTreeNode?*root,?int?*max)??
  • {??
  • ????//這個(gè)函數(shù)的主要功能是判斷root不為空,且給max賦初值??
  • ????if?(root?==?NULL?||?max?==?NULL)???
  • ????{??
  • ????????return?-1;??
  • ????}??
  • ????*max?=?0;??
  • ????return?DistanceCore(root,?max);??
  • }??
  • ??
  • int?DistanceCore(BinaryTreeNode?*root,?int?*max)??
  • {??
  • ????//如果節(jié)點(diǎn)是葉子節(jié)點(diǎn),則返回0——深度??
  • ????if?(root->m_pLeft?==?NULL?&&?root->m_pRight?==?NULL)???
  • ????{??
  • ????????return?0;??
  • ????}??
  • ??
  • ????//保存左右子樹(shù)的最大深度??
  • ????int?lDistance?=?0;??
  • ????int?rDistance?=?0;??
  • ??
  • ????//左子樹(shù)不為空,返回當(dāng)前節(jié)點(diǎn)到左子樹(shù)的最大深度??
  • ????if?(root->m_pLeft?!=?NULL)???
  • ????{??
  • ????????lDistance?=?1?+?DistanceCore(root->m_pLeft,?max);??
  • ????}??
  • ??
  • ????if?(root->m_pRight?!=?NULL)???
  • ????{??
  • ????????rDistance?=?1?+?DistanceCore(root->m_pRight,?max);??
  • ????}??
  • ??
  • ????//遍歷到當(dāng)前節(jié)點(diǎn)時(shí),能獲得的最大距離??
  • ????if?(lDistance?+?rDistance?>?*max)???
  • ????{??
  • ????????//保存當(dāng)前獲得的最大距離??
  • ????????*max?=?lDistance?+?rDistance;??
  • ????}??
  • ????//返回左右子樹(shù)中,深度較大的一個(gè)??
  • ????return?lDistance?>?rDistance???lDistance?:?rDistance;??
  • }??
  • ??
  • ??
  • //為了測(cè)試程序?qū)懙妮o助函數(shù),在樹(shù)的最最右邊插入一個(gè)新的節(jié)點(diǎn)??
  • int?InsertNodeAtMostRight(BinaryTreeNode?*?root,?BinaryTreeNode?*?node)??
  • {??
  • ????if?(root?==?NULL?||?node?==?NULL)???
  • ????{??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????while?(root->m_pRight?!=?NULL)???
  • ????{??
  • ????????root?=?root->m_pRight;??
  • ????}??
  • ??
  • ????root->m_pRight?=?node;??
  • ????return?0;??
  • }?

  • 總結(jié)

    以上是生活随笔為你收集整理的二叉树分析(两点最大距离)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。