1. 树结构
const tree = {
val: 'a',
children: [
{
val: 'b',
children: [
{
val: 'd',
children: [],
},
{
val: 'e',
children: [],
}
],
},
{
val: 'c',
children: [
{
val: 'f',
children: [],
},
{
val: 'g',
children: [],
}
],
}
],
}
2. 深度优先遍历DFS
- 访问根节点
- 对根节点的children挨个进行深度优先遍历
const dfs = (root) => {
console.log(root.val);
root.children.forEach(dfs);
}
dfs(tree)
>a
>b
>d
>e
>c
>f
>g
3. 广度优先遍历BFS
- 新建一个队列,把根节点入队;
- 把队头出队并访问;
- 把队头的children挨个入队;
- 重复第二、三步,直到队列为空
const bfs = (root) => {
const q = [root];
while (q.length) {
const n = q.shift();
console.log(n.val);
n.children.forEach(child => {
q.push(child);
});
}
}
bfs(tree);
>a
>b
>c
>d
>e
>f
>g
4. JavaScript中的二叉树
const binaryTree = {
val: 1,
left: {
val: 2,
left: null,
right: null
},
right: {
val: 3,
left: null,
right: null
}
};
5. 二叉树的先序遍历
- 访问根节点
- 对根节点的左子树进行先序遍历
- 对根节点的右子树进行先序遍历
const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
}
};
5-1. 先序遍历递归代码
const preorder = (root) => {
if (!root) { return; }
console.log(root.val);
preorder(root.left);
preorder(root.right);
}
preorder(bt);
5-2. 先序遍历非递归代码
const preorder = (root) => {
const stack = [];
while(root || stack.length){
while(root){
console.log(root.val);
stack.push(root);
root = root.left;
}
if(stack.length){
root = stack.pop();
root = root.right;
}
}
}
>1
>2
>4
>5
>3
>6
>7
6. 二叉树的中序遍历
- 对根节点的左子树进行中序遍历
- 访问根节点
- 对根节点的右子树进行中序遍历
const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
}
};
6-1. 中序遍历递归代码
const inorder = (root) => {
if (!root) { return; }
inorder(root.left);
console.log(root.val);
inorder(root.right);
}
inorder(bt);
6-2. 中序遍历非递归代码
const inorder = (root) => {
const stack = [];
while(root || stack.length){
while(root){
stack.push(root);
root = root.left;
}
if(stack.length){
root = stack.pop();
console.log(root.val);
root = root.right;
}
}
}
>4
>2
>5
>1
>6
>3
>7
7. 二叉树的后序遍历
- 对根节点的左子树进行中序遍历
- 对根节点的右子树进行中序遍历
- 访问根节点
const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
}
};
7-1. 后续遍历递归代码
const postorder = (root) => {
if (!root) { return; }
postorder(root.left);
postorder(root.right);
console.log(root.val);
}
postorder(bt);
7-2. 后续遍历非递归代码
const postorder = (root) => {
if (!root) { return; }
const stack = [root];
const OutputStack = [];
while (stack.length) {
const node = stack.pop();
OutputStack.push(node);
if (node.left) {
stack.push(node.left);
}
if (node.right) {
stack.push(node.right);
}
}
while (OutputStack.length) {
const node = OutputStack.pop();
console.log(node.val);
}
}
>4
>5
>2
>6
>7
>3
>1