一、深度优先和广度优先
- 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次
- 广度优先遍历:从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。
1、深度优先:
采用的是堆栈的形式, 即先进后出,深度优先有回溯的操作(没有路走了需要回头)所以相对而言时间会长一点
const data = [
{
name: 'a',
children: [
{ name: 'b', children: [{ name: 'e' }] },
{ name: 'c', children: [{ name: 'f' }] },
{ name: 'd', children: [{ name: 'g' }] },
],
},
{
name: 'a2',
children: [
{ name: 'b2', children: [{ name: 'e2' }] },
{ name: 'c2', children: [{ name: 'f2' }] },
{ name: 'd2', children: [{ name: 'g2' }] },
],
}
]
//深度优先
function byDeepth(data) {
let result = []
const map = (item) => {
result.push(item.name)
item.children && item.children.forEach((item) => map(item))
}
data.forEach((item) => {
map(item)
})
return result.join(',')
}
console.time('深度优先')
console.log('深度优先', byDeepth(data))
console.timeEnd('深度优先')
用时间:
2、广度优先
广度优先需要先记录所有的节点占用空间大
// 广度遍历, 创建一个执行队列, 当队列为空的时候则结束
function byBreadth(data) {
let result = []
let queque = data
while (queque.length > 0) {
result.push(queque[0].name)
if (queque[0].children) {
queque = queque.concat(queque[0].children)
}
queque.shift()// 删除第一项
}
return result.join(',')
}
console.time('广度优先')
console.log('广度优先', byBreadth(data))
console.timeEnd('广度优先')
二、二叉树遍历
- 先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。
- 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。
- 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根
- 层序遍历: 同广度优先遍历
1、先序遍历
根节点=>左子树=>右子树
遍历顺序为:ABDEGHCFI
在这里插入代码片
var headMap = function (root) {
let res =[]
function traversal (root) {
if (root !== null) {
res.push(root.val) // 根节点
if (root.left) {
traversal(root.left) // 递归遍历左子树
}
if (root.right) {
traversal(root.right) // 递归遍历左子树
}
}
}
traversal(root)
return res
}
2、中序遍历
左子树=>根节点=>右子树
遍历顺序为ABCDEFGHI
var middleMap = function (root) {
let res =[]
function traversal (root) {
if (root !== null) {
if (root.left) {
traversal(root.left) // 递归遍历左子树
}
res.push(root.val) // 根节点
if (root.right) {
traversal(root.right) // 递归遍历左子树
}
}
}
traversal(root)
return res
}
3、后序遍历
左子树=>右子树=>根节点
遍历顺序为ABCDEFGHI
var lastMap = function (root) {
let res =[]
function traversal (root) {
if (root !== null) {
if (root.left) {
traversal(root.left) // 递归遍历左子树
}
if (root.right) {
traversal(root.right) // 递归遍历左子树
}
res.push(root.val) // 根节点
}
}
traversal(root)
return res
}
4、后序遍历
从上到下,从左到右一层一层遍历的顺序
历顺序为ABCDEFGHI
var levelMap = function (root) {
let res =[]
function traversal (root, depth) {
if (root !== null) {
if (!res[depth]) {
res[depth] = [];
};
res[depth].push(root.val)
if (root.left) {
traversal(root.left, depth + 1) // 递归遍历左子树
}
if (root.right) {
traversal(root.right, depth + 1) // 递归遍历左子树
}
}
}
traversal(root, 0)
return res
}