昨天同事问了句:"如何在树结构中根据指定ID查找所有的child?"
对于平时总是在CURD的我来说还算是个有趣的事情,我需要处理的结构是部门
var arr = [
{v: 1,child : [
{v: 2,child : [
{v: 3,child : [
{v: 4,child : [
{v: 5,child : [
{v: 6,child : []},
]},
]},
]},{v: 7,child : [
{v: 8,child : [
{v: 9,child : [
{v: 10,child : []},
]},
]},
]},
{v:11,child : [
{v: 12,child : [
{v: 13,child : [
{v: 14,child : [
{v: 15,child : []},
]},
]},
]},
{v: 16,child : [
{v: 17,child : [
{v: 18,child : []},
]},
]},
]},
{v: 19,child : [
{v: 20,child : []},
]},
]},
]},
]
是一个常见的节点深度与子节点数量都不明确的结构。
深度优先遍历(DFS)与广度优先遍历(BFS)
查找这种树形结构有两种方案 深度优先
和广度优先
深度优先遍历:从根节点出发,沿着左子树方向进行纵向遍历,直到找到叶子节点为止。然后回溯到前一个节点,进行右子树节点的遍历,直到遍历完所有可达节点为止。
广度优先遍历:从根节点出发,在横向遍历树层段节点的基础上纵向遍历树的层次。
接下来实现功能
/**
* 深度优先查找
* @param {Array} array 要遍历的结构
* @param {Number} id 要寻找的
* @param {String} str 记录路径,如果你不需要可以去掉
*/
function getchild_dfs(array,id,str){
console.log(str);
for (let i = 0; i < array.length; i++) {
str += '->' + array[i]['v'];
if (array[i]['v'] === id) {
return array[i].child;
}else{
var res = getchild_dfs(array[i].child,id,str);
if (res) {
return res;
}
}
}
}
/**
* 广度优先
* @param {Array} array 要遍历的结构
* @param {Number} id 要寻找的
* @param {String} str 记录路径,如果你不需要可以去掉
*/
function getchild_bfs(array,id,str){
var childs = [];
console.log(str);
for (let i = 0; i < array.length; i++) {
str += '->' + array[i]['v'];
if (array[i]['v'] === id) {
return array[i].child;
}else{
childs = childs.concat(array[i].child);
}
}
return getchild_bfs(childs,id,str);
}
const str = '0';
console.log('-------深度优先----------');
console.info(getchild_dfs(arr,17,str));
console.log('--------广度优先---------');
console.info(getchild_bfs(arr,17,str));
打印结果:
-------深度优先----------
0
0->1
0->1->2
0->1->2->3
0->1->2->3->4
0->1->2->3->4->5
0->1->2->3->4->5->6
0->1->2->3->7
0->1->2->3->7->8
0->1->2->3->7->8->9
0->1->2->3->7->8->9->10
0->1->2->3->7->11
0->1->2->3->7->11->12
0->1->2->3->7->11->12->13
0->1->2->3->7->11->12->13->14
0->1->2->3->7->11->12->13->14->15
0->1->2->3->7->11->12->16
[ { v: 18, child: [] } ]
--------广度优先---------
0
0->1
0->1->2
0->1->2->3->7->11->19
0->1->2->3->7->11->19->4->8->12->16->20
[ { v: 18, child: [] } ]