二叉树的遍历
二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
结构
1
/ \
2 3
/ \ \
4 5 6
二叉树的遍历分为深度优先遍历(DFS)和广度优先遍历(BFS),深度遍历有前(先)序、中序以及后序三种遍历方法,广度遍历即我们寻常所说的层次遍历
深度优先遍历(DFS)
深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.
思路
深度优先遍历图的方法是,从图中某顶点v出发:
(1)访问顶点v;
(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。
前序遍历
首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树,js代码:
var postorder = function (root) {
let res = []
if (root == null) {
return res
}
let dlr = (root) => {
if (!root) {
return null
}
res.push(root.val)
dlr(root.left)
dlr(root.right)
}
dlr(root)
return res
};
示例结果:[1, 2, 4, 5, 3, 6]
中序遍历
首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树,js代码:
var postorder = function (root) {
let res = []
if (root == null) {
return res
}
let ldr = (root) => {
if (!root) {
return
}
ldr(root.left)
res.push(root.val)
ldr(root.right)
}
ldr(root)
return res
};
示例结果:[4, 2, 5, 1, 3, 6]
后序遍历
首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根,js代码:
var postorder = function (root) {
let res = []
if (root == null) {
return res
}
let lrd = (root) => {
if (!root) {
return
}
lrd(root.left)
lrd(root.right)
res.push(root.val)
}
lrd(root)
return res
};
示例结果:[4, 5, 2, 6, 3, 1]
广度优先遍历(BFS)
是最简便的图的搜索算法之一,英文全称是Breadth First Search。 BFS并不使用经验法则算法。从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。一般的实验里,其邻居节点尚未被检验过的节点会被放置在一个被称为 open 的容器中(例如队列或是链表),而被检验过的节点则被放置在被称为 closed 的容器中。
思路
给定图G=<V,E>和一个可以识别的源结点s,广度优先搜索对图G中的边进行系统性的探索来发现可以从源结点到达所有节点的路径。该算法能够计算出从源结点s到每个可到达的结点的距离,同时生成一颗广度优先搜索树。该数已源结点s为根节点,包含所有的可能从s到达的点。对于每一个从源结点s可以达到的jiedianv,在广度优先搜索树里面从结点s到达结点v的简单路径对应的就是s到v的最短路径。
层次遍历
即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同),js代码:
var postorder = function (root) {
let res = []
if (root == null) {
return res
}
let bfs = (root, i) => {
if (!root) {
return
}
if (!res[i]) {
res[i] = []
}
res[i].push(root.val)
bfs(root.left, i + 1)
bfs(root.right, i + 1)
}
bfs(root, 0)
return res
};
示例结果:[[1], [2, 3], [4, 5, 6]]