題目1:輸入乙個整數和一棵二叉樹。從樹的根節點開始往下訪問一直到葉節點所經過的所有節點形成一條路徑。列印出和輸入整數相等的所有路徑。
思路:當訪問到某一節點時,把該節點新增到路徑上,並累加當前節點的值。如果當前節點為葉節點並且當前路徑的和剛好等於輸入的整數,則當前的路徑符合要求,我們把它列印出來。如果當前節點不是葉節點,則繼續訪問它的子節點。當前節點訪問結束後,遞迴函式將自動回到父節點。因此我們在函式退出之前要在路徑上刪除當前節點並減去當前節點的值,以確保返回父節點時路徑剛好是根節點到父節點的路徑。
void findallpath(btreenode *proot, int expectednum, vector& path, int currentsum)
currentsum += proot->m_nvalue;
path.push_back(proot->m_nvalue);
bool isleaf = (proot->m_pleft==null) && (proot->m_pright==null);
if (isleaf && (currentsum==expectednum))
if (proot->m_pright)
}currentsum -= proot->m_nvalue;
path.pop_back();
}
題目2:二叉樹兩個結點的最低共同父結點
變種1:二叉樹是一種特殊的二叉樹:查詢二叉樹(位於左子樹上的結點都比父結點小,而位於右子樹上的結點都比父結點大)。此時我們只需要從根節點開始和兩個結點進行比較,如果當前結點的值比兩個結點都大,則最低的共同父結點一定在當前結點的左子樹中。如果當前結點的值比兩個結點都小,則最低的共同父結點一定在當前結點的右子樹中。如果當前結點的值大於乙個結點的值而小於另外乙個結點的值,則當前節點就是所要查詢的最低共同父結點;
bstreenode* getlastcommonparent(bstreenode* proot, bstreenode* pnode1, bstreenode* pnode2)
if(proot->m_nvaluem_nvalue && proot->m_nvaluem_nvalue)
if((proot->m_nvaluem_nvalue && proot->m_nvalue>pnode2->m_nvalue) ||
(proot->m_nvalue>pnode1->m_nvalue && proot->m_nvaluem_nvalue))
return proot;
return null;
}
思路1:首先判斷乙個結點的子樹中是不是包含了另外乙個結點,然後從根節點開始,判斷當前結點為根的樹中左右子樹是不是包含我們要找的兩個結點,如果兩個結點都出現在它的左子樹中,那最低的共同父結點也出現在它的左子樹中。如果兩個節點都出現在它的右子樹中,那最低的共同父結點也出現在它的右子樹中。如果兩個結點乙個出現在左子樹中,乙個出現在右子樹中,那當前的結點就是最低的共同父結點。
bool hasnode(btreenode* proot, btreenode* pnode)
btreenode* getlastcommonparent(btreenode* proot, btreenode* pnode1, btreenode* pnode2)
if(blefthasnode1 && blefthasnode2)
bool brighthasnode1 = false;
bool brighthasnode2 = false;
if(proot->m_pright != null)
if(brighthasnode1 && brighthasnode2)
if((blefthasnode1 & brighthasnode2) || (blefthasnode2 & brighthasnode1)) return proot;
return null;
}
注意:思路1存在重複遍歷,故時間複雜度為o(n2)
;
變種2:樹不一定是二叉樹,每個結點都有乙個指標指向它的父結點。於是我們可以從任何乙個結點出發,得到乙個到達樹根結點的單向鍊錶,然後這個問題就轉化成了求兩個單向鍊錶的第乙個公共結點。
思路2:為兩個結點分別得到乙個由根結點開始的路徑(以鍊錶形式儲存),求這兩個路徑的最後乙個公共結點即可;
bool getnodepath(btreenode* proot, btreenode* pnode, list& path)
btreenode* getlastcommonnode(list& path1, list& path2)
return null;
}btreenode* getlastcommonparent(btreenode* proot, btreenode* pnode1, btreenode* pnode2)
注意:思路2**實現的時間複雜度為o(n),但由於使用了兩個鍊錶來儲存路徑,故其空間複雜度為o(logn);
題目3:求乙個二叉樹任意兩個節點之間的距離
思路:為兩個節點分別儲存乙個從根節點開始的路徑(鍊錶形式儲存),找到這兩個路徑的最後乙個公共結點,計算出兩個節點到此公共結點的距離之和即可。
bool getnodepath(btreenode* proot, btreenode* pnode, list& path)
int getlastcommonnodeindex(list& path1, list& path2)
return index;
}int getdistanceoftwonodes(btreenode* proot, btreenode* pnode1, btreenode* pnode2)
題目4:求二叉樹中結點的最大距離(樹的直徑)
思路:距離最遠的兩點必然在以某個結點為根的子樹上,它們間的路徑必然經過該子樹的根節點,因而,以任意乙個節點b為根的子樹,計算出經過該子樹結點b的最大距離,則所有最大距離的最大值就是所要求的二叉樹的最大距離,即「樹的直徑」。而經過數的根節點的最大距離為:左子樹的高度+右子樹的高度(假設空節點的高度為-1,根節點高度為0)。
int getmaxdistace(btreenode* proot, int& maxdist)
題目5:求二叉樹的深度
思路:二叉樹的深度等於其左右子樹深度的較大值加1,注意如果乙個樹只有乙個節點的話,其深度為1(高度為0!)。
int getdepth(btreenode* proot)
,
二叉樹題目
struct treenode treenode left treenode right 遞迴解法 如果二叉樹為空,節點個數為0 如果二叉樹不為空,那麼節點個數 左子樹結點個數 右子樹結點個數 1 int getnodenum treenode root 如果二叉樹為空,二叉樹的深度為0 如果二叉樹...
二叉樹題目
include include includeusing namespace std void print postorder int n,char pre,char in n代表節點個數,pre前 in 中 post後,不建樹用void int main void return 0 根據後中求層次...
C 二叉樹操作集錦
測試用例 10 5 3 3 2 11 3 2 1 binarytree.cpp 定義控制台應用程式的入口點。include stdafx.h include include include includeusing namespace std templatestruct treenode 1.生成...