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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树和为某种所有路径

發布時間:2024/9/30 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树和为某种所有路径 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:輸入一個整數和一棵二元樹。打印出和與輸入整數相等的所有路徑,從樹的根結點開始往下訪問一直到葉結點所經過的所有結點形成一條路徑。

分析:這道題考查對二叉樹遍歷方式的理解,采用后序遍歷,如果把二叉樹看成圖,就是圖的深度遍歷。使用變量存放當前遍歷的路徑和,當訪問到某一結點時,把該結點添加到路徑上,并累加當前結點的值。如果當前結點為葉結點并且當前路徑的和剛好等于輸入的整數,則當前的路徑符合要求,我們把它打印出來。如果當前結點不是葉結點,則繼續訪問它的子結點。當前結點訪問結束后,遞歸函數將自動回到父結點,因此我們在函數退出之前要在路徑上刪除當前結點并減去當前結點的值,以確保返回父結點時路徑剛好是根結點到父結點的路徑。

二元樹結點的數據結構定義為:

view plaincopy to clipboardprint?
  • struct?BSTreeNode??
  • {??
  • ????struct?BSTreeNode()??
  • ????{??
  • ????????m_pLeft?=?NULL;??
  • ????????m_pRight?=?NULL;??
  • ????}??
  • ????int?m_nValue;???????????//?value?of?node??
  • ????BSTreeNode?*m_pLeft;????//?left?child?of?node??
  • ????BSTreeNode?*m_pRight;???//?right?child?of?node??
  • };??
  • 遞歸求解代碼如下:

    view plaincopy to clipboardprint?
  • ///??
  • //?Find?paths?whose?sum?equal?to?expected?sum??
  • ///??
  • void?FindPath??
  • (??
  • ?BSTreeNode*????????pTreeNode,??????//?a?node?of?binary?tree??
  • ?int????????????????expectedSum,????//?the?expected?sum??
  • ?std::vector<int>&??path,???????????//?a?path?from?root?to?current?node??
  • ?int&???????????????currentSum??????//?the?sum?of?path??
  • ?)??
  • {??
  • ????if(!pTreeNode)??
  • ????????return;??
  • ??
  • ????currentSum?+=?pTreeNode->m_nValue;??
  • ????path.push_back(pTreeNode->m_nValue);??
  • ??
  • ????//?if?the?node?is?a?leaf,?and?the?sum?is?same?as?pre-defined,??
  • ????//?the?path?is?what?we?want.?print?the?path??
  • ????bool?isLeaf?=?(!pTreeNode->m_pLeft?&&?!pTreeNode->m_pRight);??
  • ????if(currentSum?==?expectedSum?&&?isLeaf)??
  • ????{??
  • ????????std::vector<int>::iterator?iter?=?path.begin();??
  • ????????for(;?iter?!=?path.end();?++?iter)??
  • ????????????printf("%d\t",*iter);??
  • ????????printf("\n");??
  • ????}??
  • ??
  • ????//?if?the?node?is?not?a?leaf,?goto?its?children??
  • ????if(pTreeNode->m_pLeft)??
  • ????????FindPath(pTreeNode->m_pLeft,?expectedSum,?path,?currentSum);??
  • ????if(pTreeNode->m_pRight)??
  • ????????FindPath(pTreeNode->m_pRight,?expectedSum,?path,?currentSum);??
  • ??
  • ????//?when?we?finish?visiting?a?node?and?return?to?its?parent?node,??
  • ????//?we?should?delete?this?node?from?the?path?and??
  • ????//?minus?the?node's?value?from?the?current?sum??
  • ????currentSum?-=?pTreeNode->m_nValue;//我認為沒有必要傳currentSum的引用,所以在這里也不需要減 ?
  • ????path.pop_back();??
  • }??
  • </int></int>??
  • 擴展題:如果將條件放寬,計算和的路徑改為從根節點到葉子節點路徑上任意連續子路徑呢?
    條件改變之后,難度有所增加,堆棧中光存放從root到當前節點的和顯然不夠,需要對堆棧中的元素做出改變,使之存放堆棧當前位置到當前遍歷節點的路徑和,元素類型定義如下:

    view plaincopy to clipboardprint?
  • class?StackElement??
  • {??
  • public:??
  • ????StackElement(struct?BSTreeNode*?node,?int?s){pNode?=?node;sum?=?s;};??
  • ??
  • ????void?AddValue(int?v){sum+=v;}??
  • ????int?GetValue(){return?sum;}??
  • ??
  • ????struct?BSTreeNode*?pNode;???//二叉樹節點指針,由于不采用遞歸,因此必須保持節點指針??
  • ????int?sum;????????????????????//從當前遍歷節點到*pNode這段路徑的和??
  • };??
  • 在這里不適用遞歸,而采用另外的一種求解方式。

    view plaincopy to clipboardprint?
  • void?BSTreeSumWay(struct?BSTreeNode*?root,int?sum)??
  • {??
  • ????assert(root);??
  • ??
  • ????vector<stackelement>?way;??
  • ??
  • ????while?(root?||?!way.empty())??
  • ????{??
  • ????????while(root)??
  • ????????{??
  • ??
  • ????????????StackElement?temp(root,0);??
  • ????????????way.push_back(temp);??
  • ??
  • ????????????//路徑上增加了root,因此從way_iter->pNode到*root的路徑sum要更新??
  • ????????????vector<stackelement>::iterator?way_iter?=?way.begin();??
  • ????????????for?(;way_iter?!=?way.end();?way_iter++)??
  • ????????????{??
  • ????????????????way_iter->AddValue(root->m_nValue);??
  • ????????????????if?(sum?==?way_iter->GetValue())??
  • ????????????????{??
  • ????????????????????//打印路徑??
  • ????????????????????vector<stackelement>::iterator?print_iter?=?way_iter;??
  • ????????????????????for?(;print_iter?!=?way.end();print_iter++)??
  • ????????????????????{??
  • ????????????????????????printf("%d\t",print_iter->pNode->m_nValue);??
  • ????????????????????}??
  • ????????????????????printf("\n");??
  • ????????????????}??
  • ????????????}??
  • ??
  • ????????????root?=?root->m_pLeft;??
  • ????????}??
  • ??
  • ????????//右子樹為空或者剛從右子樹返回??
  • ????????while?(way.rbegin()->pNode->m_pRight==NULL?||?root==way.rbegin()->pNode->m_pRight)??
  • ????????{??
  • ??
  • ????????????root?=?way.rbegin()->pNode;??
  • ??
  • ????????????//路徑上減少了最后一個節點,因此路徑sum要更新??
  • ????????????int?v?=?-way.rbegin()->pNode->m_nValue;??
  • ????????????way.pop_back();??
  • ????????????vector<stackelement>::iterator?way_iter?=?way.begin();??
  • ????????????for?(;way_iter?!=?way.end();?way_iter++)??
  • ????????????{??
  • ????????????????way_iter->AddValue(v);??
  • ????????????}??
  • ??
  • ????????????if?(way.empty())??
  • ????????????{??
  • ????????????????break;??
  • ????????????}??
  • ??
  • ????????}??
  • ??
  • ????????if?(way.empty())??
  • ????????????break;??
  • ??
  • ????????root?=?way.rbegin()->pNode->m_pRight;??
  • ??
  • ????}??
  • ??
  • }??
  • </stackelement></stackelement></stackelement></stackelement>??
  • 網絡轉載請注明:轉載自程序員面試之家


    總結

    以上是生活随笔為你收集整理的二叉树和为某种所有路径的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。