概念
各ノードの二分木は、ツリーの子ノードを最大2つまで持つことができます。
成し遂げる
JavaScriptObject
では、バイナリツリーを実装するために一般的に使用されます。上の図に示すように、バイナリツリーは次のように表すことができます。
const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null
},
right: {
val: 5,
left: {
val: 8,
left: null,
right: null
},
right: {
val: 9,
left: null,
right: null
}
}
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null
},
right: {
val: 7,
left: null,
right: null
}
}
};
トラバース
プレオーダートラバーサル
- ルートノードにアクセスします
- ルートに左部分木のBEの前順
- ルートに右部分木のBEの前順
再帰バージョン:
// 递归先序遍历: 根 - 左 - 右
const preorder = root => {
if (!root) {
return; }
console.log(root.val); // 根
preorder(root.left); // 左
preorder(root.right); // 右
};
非再帰バージョン:
// 递归先序遍历(非递归)
const preorder = root => {
if (!root) {
return; }
const stack = [root];
while (stack.length) {
// 栈顶元素
const n = stack.pop();
console.log(n.val);
if (n.right) stack.push(n.right);
if (n.left) stack.push(n.left);
}
};
順序どおりの走査
- ルートに左部分木のBEの前順
- ルートノードにアクセスします
- ルートに右部分木のBEの前順
再帰バージョン:
// 递归中序遍历:左-根-右
const inorder = root => {
if (!root) {
return; }
inorder(root.left); // 左
console.log(root.val); // 根
inorder(root.right); // 右
};
非再帰バージョン:
// 递归中序遍历(非递归)
const inorder = root => {
if (!root) {
return; }
const stack = [];
let p = root;
while (stack.length || p) {
while (p) {
stack.push(p);
p = p.left;
}
const n = stack.pop();
console.log(n.val);
p = n.right
}
};
注文後のトラバーサル
- ルートに左部分木のBEの前順
- ルートに右部分木のBEの前順
- ルートノードにアクセスします
再帰バージョン:
// 递归后序遍历:左-右-根
const postorder = root => {
if (!root) {
return; }
postorder(root.left); // 左
postorder(root.right); // 右
console.log(root.val); // 根
};
非再帰バージョン:
// 递归后序遍历(非递归)
const postorder = root => {
if (!root) {
return; }
const outStack = [];
const stack = [root];
while (stack.length) {
const n = stack.pop();
outStack.push(n);
if (n.left) stack.push(n.left);
if (n.right) stack.push(n.right);
}
while (outStack.length) {
const n = outStack.pop();
console.log(n.val);
}
};