W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Question
給定一個二叉樹的前序遍歷 preorder
和中序遍歷 inorder
,請從中構(gòu)建二叉樹,返回二叉樹的根節(jié)點。
圖 12-5 構(gòu)建二叉樹的示例數(shù)據(jù)
原問題定義為從 preorder
和 inorder
構(gòu)建二叉樹,其是一個典型的分治問題。
根據(jù)以上分析,這道題是可以使用分治來求解的,但如何通過前序遍歷 preorder
和中序遍歷 inorder
來劃分左子樹和右子樹呢?
根據(jù)定義,preorder
和 inorder
都可以被劃分為三個部分。
[ 根節(jié)點 | 左子樹 | 右子樹 ]
,例如圖 12-5 的樹對應(yīng) [ 3 | 9 | 2 1 7 ]
。[ 左子樹 | 根節(jié)點 | 右子樹 ]
,例如圖 12-5 的樹對應(yīng) [ 9 | 3 | 1 2 7 ]
。以上圖數(shù)據(jù)為例,我們可以通過圖 12-6 所示的步驟得到劃分結(jié)果。
inorder
中的索引,利用該索引可將 inorder
劃分為 [ 9 | 3 | 1 2 7 ]
。inorder
劃分結(jié)果,易得左子樹和右子樹的節(jié)點數(shù)量分別為 1 和 3 ,從而可將 preorder
劃分為 [ 3 | 9 | 2 1 7 ]
。圖 12-6 在前序和中序遍歷中劃分子樹
根據(jù)以上劃分方法,我們已經(jīng)得到根節(jié)點、左子樹、右子樹在 preorder
和 inorder
中的索引區(qū)間。而為了描述這些索引區(qū)間,我們需要借助幾個指針變量。
preorder
中的索引記為 inorder
中的索引記為 inorder
中的索引區(qū)間記為 如表 12-1 所示,通過以上變量即可表示根節(jié)點在 preorder
中的索引,以及子樹在 inorder
中的索引區(qū)間。
表 12-1 根節(jié)點和子樹在前序和中序遍歷中的索引
根節(jié)點在 preorder 中的索引 |
子樹在 inorder 中的索引區(qū)間 |
|
---|---|---|
當(dāng)前樹 | ||
左子樹 | ||
右子樹 |
請注意,右子樹根節(jié)點索引中的
圖 12-7 根節(jié)點和左右子樹的索引區(qū)間表示
為了提升查詢 hmap
來存儲數(shù)組 inorder
中元素到索引的映射。
build_tree.cpp
/* 構(gòu)建二叉樹:分治 */
TreeNode *dfs(vector<int> &preorder, unordered_map<int, int> &inorderMap, int i, int l, int r) {
// 子樹區(qū)間為空時終止
if (r - l < 0)
return NULL;
// 初始化根節(jié)點
TreeNode *root = new TreeNode(preorder[i]);
// 查詢 m ,從而劃分左右子樹
int m = inorderMap[preorder[i]];
// 子問題:構(gòu)建左子樹
root->left = dfs(preorder, inorderMap, i + 1, l, m - 1);
// 子問題:構(gòu)建右子樹
root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
// 返回根節(jié)點
return root;
}
/* 構(gòu)建二叉樹 */
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
// 初始化哈希表,存儲 inorder 元素到索引的映射
unordered_map<int, int> inorderMap;
for (int i = 0; i < inorder.size(); i++) {
inorderMap[inorder[i]] = i;
}
TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorder.size() - 1);
return root;
}
圖 12-8 展示了構(gòu)建二叉樹的遞歸過程,各個節(jié)點是在向下“遞”的過程中建立的,而各條邊(即引用)是在向上“歸”的過程中建立的。
圖 12-8 構(gòu)建二叉樹的遞歸過程
每個遞歸函數(shù)內(nèi)的前序遍歷 preorder
和中序遍歷 inorder
的劃分結(jié)果如圖 12-9 所示。
圖 12-9 每個遞歸函數(shù)中的劃分結(jié)果
設(shè)樹的節(jié)點數(shù)量為 dfs()
)使用
哈希表存儲 inorder
元素到索引的映射,空間復(fù)雜度為
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: