深度優先遍歷
1) 前序遍歷
遞迴實現:
const preOrder = (root) => {
let result = [];
const traverseNode = (node) => {
if (node) {
// 先根節點
result.push(node.val);
// 然後遍歷左子樹
traverseNode(node.left);
// 再遍歷右子樹
traverseNode(node.right);
}
}
traverseNode(root);
return result;
}
非遞迴實現:
const preOrder = (root) => {
let list = [];
let stack = [];
// 當根節點不為空的時候,將根節點入棧
if (root != null) stack.push(root);
while (stack.length > 0) {
root = stack.pop();
// 先訪問根節點
list.push(root.val);
// 我們先列印左子樹,然後右子樹
// 所以先入棧的是右子樹,然後左子樹
if (root.right != null) stack.push(root.right);
if (root.left != null) stack.push(root.left);
}
return list;
}
2) 中序遍歷
遞迴實現:
const inOrder = (root) => {
let result = [];
const traverseNode = (node) => {
if (node) {
// 先遍歷左子樹
traverseNode(node.left);
// 然後根節點
result.push(node.val);
// 再遍歷右子樹
traverseNode(node.right);
}
}
traverseNode(root);
return result;
}
非遞迴實現:
const inOrder = (root) => {
let list = [];
let stack = [];
while (stack.length > 0 || root != null) {
if (root != null) {
// 如果當前節點非空,就將當前節點入棧
stack.push(root);
// 指標向當前節點的左節點方向移動
root = root.left;
} else {
// 當前節點為空,則從棧頂彈出元素
root = stack.pop();
list.push(root.val);
// 指標向右節點方向移動
root = root.right;
}
}
return list;
}
3) 後序遍歷
遞迴實現:
const postOrder = (root) => {
let result = [];
const traverseNode = (node) => {
if (node) {
// 先遍歷左子樹
traverseNode(node.left);
// 然後遍歷右子樹
traverseNode(node.right);
// 最後根節點
result.push(node.val);
}
}
traverseNode(root);
return result;
}
非遞迴實現:
const postOrder = (root) => {
let list = [];
let stack = [];
// 當根節點不為空,將根節點入棧
if (root != null) stack.push(root);
while (stack.length > 0) {
root = stack.pop();
// 由於後序遍歷輸出順序是:左=>右=>根
// 先將新增結果的順序反一下
list.unshift(root.val);
// 然後讓左子樹先入棧,後右子樹
// 這樣出棧順序就變成先右後左
if (root.left != null) stack.push(root.left);
if (root.right != null) stack.push(root.right);
}
return list;
}
廣度優先遍歷 (層序遍歷)
非遞迴實現:
const levelOrder = (root) => {
let list = [];
let queue = [];
if (root != null) queue.push(root);
while (queue.length > 0) {
let size = queue.length;
let temp = [];
for (let i=0; i<size; i++) {
// 將當前佇列元素全部出隊
root = queue.pop();
// 將結果新增到陣列中
temp.push(root.val);
// 然後將下一層的元素加入佇列
if (root.right != null) queue.push(root.right);
if (root.left != null) queue.push(root.left);
}
list.push(temp);
}
return list;
}