劍指Offer第6題(重建二叉樹)

2021-09-29 14:06:16 字數 4289 閱讀 6252

(本部落格旨在個人總結回顧)

題目描述:

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中不含有重複的數字。例如輸入前序遍歷序列為和中序遍歷序列,這重建出如下圖所示的二叉樹並輸出他的頭結點。

二叉樹結點的定義如下:

struct binarytreenode

解決思路:首先我們要明白前、中、後序遍歷的含義:

前序遍歷(preorder):先訪問父節點(最前訪問),再訪問左結點,再訪問右結點;

中序遍歷(inorder):先訪問左節點,再訪問父節點(中間訪問),再訪問右節點;

後續遍歷(postorder):先訪問左結點,再訪問右節點,再訪問父節點(最後訪問);

①前序遍歷序列中第乙個為父節點,在中序遍歷序列中父節點的左邊資料為左子樹,右邊資料為右子樹。

②而左子樹和右子樹同樣是二叉樹。

重建二叉樹函式:

/*

* @name builtbinarytreenode

* @brief 通過前序遍歷序列和中序遍歷序列重建二叉樹(無重複結點值)

* @param [in] int * ppreorder 前序遍歷序列

* @param [in] int * pinorder 中序遍歷序列

* @param [in] int nlength 二叉樹結點數

* @return binarytreenode*

*/binarytreenode* builtbinarytree(int* ppreorder, int* pinorder, int nlength)

binarytreenode* pnode = new binarytreenode();

pnode->m_nvalue = ppreorder[0];

//父節點下標,等於左子樹結點個數

int ninorderparent = 0;

while (ninorderparent < nlength)

else

}pnode->m_pleft = builtbinarytree(ppreorder + 1, pinorder, ninorderparent);

pnode->m_pright = builtbinarytree(ppreorder + 1 + ninorderparent, pinorder + ninorderparent + 1, nlength - ninorderparent - 1);

return pnode;

}

完成測試例子:

#include "stdafx.h"

#include using namespace std;

//二叉樹結點

struct binarytreenode;/*

* @name builtbinarytreenode

* @brief 通過前序遍歷序列和中序遍歷序列重建二叉樹(無重複結點值)

* @param [in] int * ppreorder 前序遍歷序列

* @param [in] int * pinorder 中序遍歷序列

* @param [in] int nlength 二叉樹結點數

* @return binarytreenode*

*/binarytreenode* builtbinarytree(int* ppreorder, int* pinorder, int nlength)

binarytreenode* pnode = new binarytreenode();

pnode->m_nvalue = ppreorder[0];

//父節點下標,等於左子樹結點個數

int ninorderparent = 0;

while (ninorderparent < nlength)

else

}pnode->m_pleft = builtbinarytree(ppreorder + 1, pinorder, ninorderparent);

pnode->m_pright = builtbinarytree(ppreorder + 1 + ninorderparent, pinorder + ninorderparent + 1, nlength - ninorderparent - 1);

return pnode;}/*

* @name printpreorder

* @brief 前序遍歷二叉樹並列印(遞迴)

* @param [in] binarytreenode* pbinarytreehead 二叉樹根節點

* @return void

*/void printpreorder(binarytreenode* pbinarytreehead)}/*

* @name printinorder

* @brief 中序遍歷二叉樹並列印(遞迴)

* @param [in] binarytreenode * pbinarytreehead

* @return void

*/void printinorder(binarytreenode* pbinarytreehead)

}int _tmain(int argc, _tchar* ar**)

; int arrayinorder1 = ;

binarytreenode* plistnode = builtbinarytree(arraypreorder1, arrayinorder1, sizeof(arraypreorder1) / sizeof(arraypreorder1[0]));

cout << "重建二叉樹的前序遍歷:" << endl;

printpreorder(plistnode);

cout << endl << "重建二叉樹的中序遍歷:" << endl;

printinorder(plistnode);

cout << endl;

//測試例子2(每個父節點只有左子節點)

int arraypreorder2 = ;

int arrayinorder2 = ;

plistnode = builtbinarytree(arraypreorder2, arrayinorder2, sizeof(arraypreorder2) / sizeof(arraypreorder2[0]));

cout << "重建二叉樹的前序遍歷:" << endl;

printpreorder(plistnode);

cout << endl << "重建二叉樹的中序遍歷:" << endl;

printinorder(plistnode);

cout << endl;

//測試例子3(每個父節點只有右子節點)

int arraypreorder3 = ;

int arrayinorder3 = ;

plistnode = builtbinarytree(arraypreorder3, arrayinorder3, sizeof(arraypreorder3) / sizeof(arraypreorder3[0]));

cout << "重建二叉樹的前序遍歷:" << endl;

printpreorder(plistnode);

cout << endl << "重建二叉樹的中序遍歷:" << endl;

printinorder(plistnode);

cout << endl;

//測試例子4(無節點)

plistnode = builtbinarytree(null, null, 10);

cout << "重建二叉樹的前序遍歷:" << endl;

printpreorder(plistnode);

cout << endl << "重建二叉樹的中序遍歷:" << endl;

printinorder(plistnode);

cout << endl;

system("pause");

return 0;

}

執行結果:

劍指offer 第6題重建二叉樹

public class test 6 根據前序遍歷和中序遍歷構建二叉樹 前序遍歷序列 前序遍歷開始位置 前序遍歷結束位置 中序遍歷序列 中序遍歷開始位置 中序遍歷結束位置 構建的樹的根節點 前序遍歷和中序遍歷序列 private static treenode reconstructbinaryt...

劍指offer第5題 重建二叉樹

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如,給出 前序遍歷 preorder 3,9,20,15,7 中序遍歷 inorder 9,3,15,20,7 返回如下的二叉樹 3 9 20 15 7 限制 0 節點個數 5000 前序...

劍指offer程式設計題《重建二叉樹》

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。我們都知道,通過前序遍歷和中序遍歷或後序遍歷和中序遍歷可以唯一確定一棵二叉樹。前序 根 左 右 中序 左 根 右 後序 左 右 根 ...