二叉樹簡介
基本結構:
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
二叉樹的前序、中序、後序遍歷的定義:
前序遍歷:對任一子樹,先訪問跟,然後遍歷其左子樹,最後遍歷其右子樹;
中序遍歷:對任一子樹,先遍歷其左子樹,然後訪問根,最後遍歷其右子樹;
後序遍歷:對任一子樹,先遍歷其左子樹,然後遍歷其右子樹,最後訪問根。
題目1 二叉樹遍歷
1.1 題目描述
給定一棵二叉樹的前序遍歷和中序遍歷,求其後序遍歷
輸入描述:
兩個字符串,其長度n均小於等於26。
第一行爲前序遍歷,第二行爲中序遍歷。
二叉樹中的結點名稱以大寫字母表示:A,B,C....最多26個結點。
輸出描述:
輸入樣例可能有多組,對於每組測試樣例,
輸出一行,爲後序遍歷的字符串。
樣例:
輸入
ABC
BAC
FDXEAG
XDEFAG
輸出
BCA
XEDGAF
1.2 解題思路
前序遍歷:跟節點 + 左子樹前序遍歷 + 右子樹前序遍歷
中序遍歷:左子樹中序遍歷 + 跟節點 + 右字數中序遍歷
後序遍歷:左子樹後序遍歷 + 右子樹後序遍歷 + 跟節點
1.前序遍歷的頭部爲跟節點
2.中序遍歷以跟節點分割,左側爲左子中序遍歷,右側爲右子樹中序遍歷
3.根據中序遍歷得到的左子樹右子樹的長度,得到左子樹的前序遍歷和右子樹的前序遍歷
1.3 代碼
let pre;
let vin;
while((pre = readline())!=null){
vin = readline();
print(getHRD(pre,vin));
}
function getHRD(pre, vin) {
if (!pre) {
return '';
}
if (pre.length === 1) {
return pre;
}
const head = pre[0];
const splitIndex = vin.indexOf(head);
const vinLeft = vin.substring(0, splitIndex);
const vinRight = vin.substring(splitIndex + 1);
const preLeft = pre.substring(1, splitIndex + 1);
const preRight = pre.substring(splitIndex + 1);
return getHRD(preLeft, vinLeft) + getHRD(preRight, vinRight) + head;
題目2 二叉樹重建
2.1 題目描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
2.2 解題思路
思路和題目1相似。
根據前序遍歷和中序遍歷的結果可以拿到:
左子中序遍歷和右側爲右子樹中序遍歷
左子樹的前序遍歷和右子樹的前序遍歷
然後遞歸左子樹和右子樹的完成重建。
2.3 代碼
function reConstructBinaryTree(pre, vin) {
if(pre.length === 0){
return null;
}
if(pre.length === 1){
return new TreeNode(pre[0]);
}
const value = pre[0];
const index = vin.indexOf(value);
const vinLeft = vin.slice(0,index);
const vinRight = vin.slice(index+1);
const preLeft = pre.slice(1,index+1);
const preRight = pre.slice(index+1);
const node = new TreeNode(value);
node.left = reConstructBinaryTree(preLeft, vinLeft);
node.right = reConstructBinaryTree(preRight, vinRight);
return node;
}