深度优先遍历和广度优先遍历属于图算法。
这里简单介绍这两种方法并使用JS实现。
一. 定义
深度优先遍历:指从某个顶点出发,首先访问这顶点,然后找出刚访问的这个结点的第一个未被访问的邻节点,然后从这个邻结点为顶点,继续找出它的下一个顶点进行访问。重复此步骤,直到所有节点被访问完为止。
广度优先遍历:从某个顶点出发,首先访问这个顶点,然后找出刚访问的这个结点的所有未被访问的邻结点,访问完后再访问这些结点中第一个邻结点的所有结点。重复此方法,直到所有节点被访问完为止。
简单来说,深度优先是自上而下的遍历搜索,广度优先是逐层遍历
二. 区别
对于算法,无非是时间复杂度与空间复杂度之间的较量
- 深度优先不需要记住所有的节点,所以占用空间小;而广度优先需要记住所有的节点,占用空间大;
- 深度优先有回溯的操作(没有路走了需要回头),所以相对而言时间会更长些。
深度优先采用的是堆栈的形式,即先进后出
广度优先则采用队列的形式,即先进先出
三. 实现(使用JS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| const data = [ { name: 'a', children: [ { name: 'b', children: [{ name: 'e' }] }, { name: 'c', children: [{ name: 'f' }] }, { name: 'd', children: [{ name: 'g' }] }, ] }, { name: 'A', children: [ { name: 'B', children: [{ name: 'E' }] }, { name: 'C', children: [{ name: 'F' }] }, { name: 'D', children: [{ name: 'G' }] }, ] } ]
function deepTraversal(data) { const result = [] data.forEach(item => { const map = data => { result.push(data.name) data.children && data.children .forEach(child => map(child)) }
map(item) }) return result.join(', ') }
function wideTraversal(data) { let result = [] let queue = data while (queue.length > 0) { [...queue].forEach(child => { queue.shift() result.push(child.name) child.children && queue.push(...child.children) }) } return result.join(', ') }
deepTraversal(data) wideTraversal(data)
|