要遍历的树结构如下:
const data = [{
label: 'parent',
children: [
{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1'
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1'
}]
}]
}
]
}];
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
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
深度优先遍历(DFS,Depth-First-Search)
实现基本原理:递归。
递归实现
// 递归实现
const deepTraversal = ((node, nodeList = []) => {
if (node.length) {
for (let i = 0; i < node.length; i++) {
const {label, children} = node[i];
nodeList.push(label);
if (children && children.length) {
deepTraversal(children, nodeList);
}
}
}
return nodeList;
});
const result = deepTraversal(data);
console.log(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
输出结果如下:
[ 'parent',
'一级 1',
'二级 1-1',
'三级 1-1-1',
'一级 2',
'二级 2-1',
'三级 2-1-1',
'二级 2-2',
'三级 2-2-1',
'一级 3',
'二级 3-1',
'三级 3-1-1',
'二级 3-2',
'三级 3-2-1' ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
基于栈实现
const deepTraversal = ((node, nodeList = []) => {
const stack = [];
if (node.length) {
stack.push(node[0]);
while (stack.length) {
const item = stack.pop();
nodeList.push(item.label);
console.log(item);
if (item.children) {
const children = item.children;
for (let i = children.length - 1; i >= 0; i--) {
stack.push(children[i]);
}
}
}
}
return nodeList;
});
const result = deepTraversal(data);
console.log(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
广度优先遍历(BFS,Breadth-First-Search)
实现原理:队列。
const bfsTraversal = ((node, nodeList = []) => {
const queue = []; // 基于队列的先进先出
if (node.length) {
queue.push(node[0]);
while (queue.length) {
const item = queue.shift();
nodeList.push(item.label);
if (item.children) {
const children = item.children;
for (let j = 0; j < children.length; j++) {
queue.push(children[j]);
}
}
}
}
return nodeList;
});
const result = bfsTraversal(data);
console.log(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
输出结果如下:
[ 'parent',
'一级 1',
'一级 2',
'一级 3',
'二级 1-1',
'二级 2-1',
'二级 2-2',
'二级 3-1',
'二级 3-2',
'三级 1-1-1',
'三级 2-1-1',
'三级 2-2-1',
'三级 3-1-1',
'三级 3-2-1' ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
深度优先搜索
深度优先搜索(depth first search),从图中也可以看出来,是从根节点开始,沿树的深度进行搜索,尽可能深的搜索分支。当节点所在的边都已经搜多过,则回溯到上一个节点,再搜索其余的边。
深度优先搜索采用栈结构,后进先出。 该算法先将当前结点的孩子全部遍历结束,再遍历同一级的节点。
递归实现
<body>
<div id='root'>
<span>123
<a href="#">
sdsd
</a>
<div>sdsd<a>这是一个a标签</a></div>
</span>
<span>456
<p>
这是一个p标签
<span>123</span>
</p>
</span>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function deepTraversal(node, nodeList) {
if (node) {
nodeList.push(node);
var children = node.children;
for (var i = 0; i < children.length; i++) {
// 每次递归的时候将需要遍历的节点和存储节点的数组传下去
deepTraversal(children[i], nodeList);
}
}
return nodeList;
}
const root = document.getElementById('root');
console.log(deepTraversal(root, nodeList=[]));
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
非递归实现
function deepTraversal(node) {
var nodeList = [];
if (node) {
var stack = [];
stack.push(node);
while (stack.length != 0) {
var childrenItem = stack.pop();
nodeList.push(childrenItem);
var childrenList = childrenItem.children;
for (var i = childrenList.length - 1; i >= 0; i--)
stack.push(childrenList[i]);
}
}
return nodeList;
}
var root = document.getElementById('root')
console.log(deepTraversal(root))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
广度优先
当使用广度优先遍历的时候,先依次遍历兄弟节点,然后遍历兄弟节点下的子节点。 广度优先遍历二叉树,也就是按层次的去遍历。依次遍历根节点,然后是左孩子和右孩子。所以要遍历完当前节点的所有孩子。根据左右孩子的顺序来输出,所以就是先进先出的原则,那么我们当然就想到了队列这个数据结构:
非递归实现
function wideTraversal(node) {
var nodes = [];
if (node != null) {
var queue = [];
queue.unshift(node);
while (queue.length != 0) {
var item = queue.shift();
nodes.push(item);
var children = item.children;
for (var i = 0; i < children.length; i++)
queue.push(children[i]);
}
}
return nodes;
}
const root = document.getElementById('root');
console.log(wideTraversal(root));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17