程式設計之美3.9:給出前序遍歷和中序遍歷,重新建立二叉樹,後序遍歷輸出。**如下:
view code
1 #include 2 #include 3對於書中的幾個擴充套件問題:4using
namespace
std;56
struct
node7;
1213
void aftertra(node*proot)
1419 aftertra(proot->m_lchild);
20 aftertra(proot->m_rchild);
21 cout
22}2324
//刪除樹的操作
25void destroytree(node*&proot)
2631 destroytree(proot->m_lchild);
32 destroytree(proot->m_rchild);
33delete proot;34}
3536
//計算樹中的節點個數
37int treesize(node*proot)
3843
return
1+treesize(proot->m_lchild)+treesize(proot->m_rchild);44}
45//
無重複字母的情況
46void rebuild(char* ppreorder,char* pinorder,int ntreelen,node**proot)
4752 node* ptmp=new
node;
53 ptmp->m_lchild=null;
54 ptmp->m_rchild=null;
55 ptmp->data=*ppreorder;
56if (*proot==null)
5760
if (ntreelen==1)61
64char* porginorder=pinorder;
65char* pleftend=pinorder;
66int ntemplen=0;67
while(*pleftend!=*ppreorder)
6873 ntemplen++;
74if (ntemplen>ntreelen)
7579 pleftend++;80}
81int nleftlen=0
;82 nleftlen=(int)(pleftend-porginorder);
83int nrightlen=0
;84 nrightlen=ntreelen-nleftlen-1;85
if (nleftlen>0)86
89if (nrightlen>0)90
93}9495
intmain()
96
1. 如果有重複字母情況會怎樣?如果有重複字母,得到的樹不一定唯一。怎樣輸出所有可能的樹?還沒想到方法,求路人指教。
2. 怎樣判斷給出的前序和中序遍歷是否合理?如果沒有字母不重複,題目**中已經給出答案:
if (ntemplen>ntreelen)
{cout<
3. 如果給出的是後序和中序遍歷,方法同上,只需要小小的修改。
4. 如果給出的是中序遍歷和層次遍歷,這個演算法的中心思想是遞迴下降. 層次遍歷的第乙個結點(記為r)即為樹根. 由中序遍歷的性質可知, 在中序序列中, r左邊的為左子樹的結點, r右邊的為右子樹的結點. 我們將r左邊的序列記為p1, r右邊的序列記為p2. 用上面的性質, 對層次序列剩下的結點, 按順序(這個最重要)判斷是左子樹還是右子樹的結點, 分別歸類組成兩個序列: 左子樹的層次遍歷序列c1和右子樹的層次遍歷序列c2. 問題就變為按p1和c1建立左子樹, 按p2和c2建立右子樹. 遞迴形成。相比較於前序和中序,多個一步是使用迴圈將層次遍歷中的節點分為左子樹層次遍歷和右子樹層次遍歷兩部分。
5. 如果給出的是前序遍歷和後序遍歷,這樣不能確定二叉樹。
6. 可見一棵樹的中序遍歷比較重要,因為中序遍歷將左右子樹都存放在根的左右兩側了。
7. 有個層次和中序遍歷生成二叉樹非遞迴演算法,有時間看看。
由前序遍歷和中序遍歷重建二叉樹
唯一的難點就是確定當前節點的左子樹的根節點和右子樹的根節點分別在前序遍歷陣列的位置。例如 先序遍歷陣列pre 1 2 3 4 5 6 7 中序遍歷陣列in 3 2 4 1 6 5 7 1是當前根節點,它在pre中的位置 pre start 0接著在in中找到1的位置,即分割點 j 3當前樹根所囊括的...
二叉樹 由前序遍歷和中序遍歷重建二叉樹
由前序遍歷和中序遍歷重建二叉樹 前序序列 1 2 3 4 5 6 中序序列 3 2 4 1 6 5 思路 前序遍歷第乙個是根節點。中序遍歷根節點左側為左子樹,根右側為右子樹。那麼先構造根節點,根節點左側都為左子樹,根右側都為右子樹。然後對左右子樹遞迴式的構造即可。封裝 binarytreenode ...
前序遍歷和中序遍歷重建二叉樹
根據先序序列和中序序列的特點我們可以知道 1 先序的第乙個節點是根節點 2 在中序序列中,根結點前邊的結點都是左子樹中的,根結點右邊的結點都是右子樹中的 3 通過左右子樹的中序序列帶入前序序列可以求出左右子樹的前序序列 4 左右子樹的前序序列第乙個元素分別是根節點的左右孩子 5 可以遞迴上述步驟來重...