一、树是什么？

2.JS中没有树，但是可以用Object和Array构建树
``````{
value: "",
label: "",
children: [
{
value: "",
label: "",
children: []
}
]
}

二、什么是深度/广度优先遍历？

深度优先遍历：尽可能深的搜索树的分支

深度优先遍历流程

1. 访问根节点
2. 对根节点的children挨个进行深度优先遍历

（递归）

代码实现

``````const tree = {
val: "a",
children: [
{
val: "b",
children: [
{
val: "d",
children: [],
},
{
val: "e",
children: [],
},
],
},
{
val: "c",
children: [
{
val: "f",
children: [],
},
{
val: "g",
children: [],
},
],
},
],
};
//深度优先遍历
const dfs = (root) => {
console.log(root.val);
root.children.forEach((child) => {dfs(child)});
}

dfs(tree);

广度优先遍历：先访问离根节点最近的节点

广度优先遍历流程

1. 新建一个队列，把根节点入队
2. 把队头出队并访问
3. 把队头的children挨个入队
4. 重复第二、三步，直到队列为空

代码实现

``````const tree = {
val: "a",
children: [
{
val: "b",
children: [
{
val: "d",
children: [],
},
{
val: "e",
children: [],
},
],
},
{
val: "c",
children: [
{
val: "f",
children: [],
},
{
val: "g",
children: [],
},
],
},
],
};
//广度优先遍历
const bfs = (root) => {
const q = [root];
while(q.length > 0) {
const n = q.shift();
console.log(n.val);
n.children.forEach(child => {
q.push(child);
})
}

}

bfs(tree);

三、二叉树的先中后序遍历

二叉树定义

``````const binaryTree = {
val: 1,
left: {
val : 2,
left: null,
right: null
},
right: {
val: 3,
left: null,
right: null
}
}

先序遍历： 根左右

1. 访问根节点
2. 对根节点的左子树进行先序遍历
3. 对根节点的右子树进行先序遍历

递归版代码实现

``````const bt = {
val: 50,
left: {
val: 10,
left: {
val: 5,
left: null,
right: null,
},
right: {
val: 15,
left: null,
right: null,
},
},
right: {
val: 70,
left: {
val: 60,
left: null,
right: null,
},
right: {
val: 80,
left: null,
right: null,
},
},
};

const preorder = (root) => {
if (!root) { return };
console.log(root.val);
preorder(root.left);
preorder(root.right);
}
// 50 10 5 15 70 60 80

preorder(bt);

非递归版代码实现

``````const bt = {
val: 50,
left: {
val: 10,
left: {
val: 5,
left: null,
right: null,
},
right: {
val: 15,
left: null,
right: null,
},
},
right: {
val: 70,
left: {
val: 60,
left: null,
right: null,
},
right: {
val: 80,
left: null,
right: null,
},
},
};

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);
}
};

// 50 10 5 15 70 60 80

preorder(bt);

中序遍历： 左根右

1. 对根节点的左子树进行中序遍历
2. 访问根节点
3. 对根节点的右子树进行中序遍历

递归版代码实现

``````const bt = {
val: 56,
left: {
val: 22,
left: {
val: 10,
left: null,
right: null,
},
right: {
val: 30,
left: null,
right: null,
},
},
right: {
val: 81,
left: {
val: 77,
left: null,
right: null,
},
right: {
val: 92,
left: null,
right: null,
},
},
};

const inorder = (root) => {
if (!root) { return; }
inorder(root.left);
console.log(root.val);
inorder(root.right);
};

// 10  22 30 56  77 81 92

inorder(bt);

非递归版代码实现

``````const bt = {
val: 56,
left: {
val: 22,
left: {
val: 10,
left: null,
right: null,
},
right: {
val: 30,
left: null,
right: null,
},
},
right: {
val: 81,
left: {
val: 77,
left: null,
right: null,
},
right: {
val: 92,
left: null,
right: null,
},
},
};

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;
}
};

// 10  22 30 56  77 81 92

inorder(bt);

后序遍历： 左右根

1. 对根节点的左子树进行后序遍历
2. 对根节点的右子树进行后序遍历
3. 访问根节点

递归版代码实现

``````const bt = {
val: 23,
left: {
val: 16,
left: {
val: 3,
left: null,
right: null,
},
right: {
val: 22,
left: null,
right: null,
},
},
right: {
val: 45,
left: {
val: 37,
left: null,
right: null,
},
right: {
val: 99,
left: null,
right: null,
},
},
};

//后序遍历
const postorder = (root) => {
if (!root) { return; }
postorder(root.left);
postorder(root.right);
console.log(root.val);
};

// 3 22 16 37 99 45 23

postorder(bt);

非递归版代码实现

``````const bt = {
val: 23,
left: {
val: 16,
left: {
val: 3,
left: null,
right: null,
},
right: {
val: 22,
left: null,
right: null,
},
},
right: {
val: 45,
left: {
val: 37,
left: null,
right: null,
},
right: {
val: 99,
left: null,
right: null,
},
},
};

const postorder = (root) => {
if (!root) { return; }
const outputStack = [];
const stack = [root];
while (stack.length) {
const n = stack.pop();
outputStack.push(n);
if (n.left) stack.push(n.left);
if (n.right) stack.push(n.right);
}
while(outputStack.length){
const n = outputStack.pop();
console.log(n.val);
}
};

postorder(bt);