这是节点结构,默认name在数组当中的所有对象中具有唯一性。当然,如果需要,可以添加利用唯一id当作标识。
interface DataFormat {
name:string,
children?:Array<DataFormat>
}
我写了一个用于遍历的数组结构和一个目标节点。testData从name为0的根节点开始开始,深度增加,每一个叶子节点都有name属性,并且可能存在children属性,children是数组结构,若存在children结构,则说明当前节点存在子节点。
const testData:DataFormat={
name:'0',
children:[{
name:'1',
children:[{
name:'11'
},{
name:'12'
}]
},{
name:'2'
},{
name:'3',
children:[{
name:'31',
children:[{
name:'311',
},{
name:'312',
children:[{
name:'3112',
}]
}]
},{
name:'32'
}]
}]
}
const node:DataFormat={name:'32'};
为了在最后能够保存得到的路径,我创建了一个outputArray用于存放保存的节点。
findFlag作为一个全局变量,在找到目标节点时进行标识,并保证在接下来的递归当中控制逻辑。
思路:树形结构遍历很容易想到用递归,对二叉树,我们采用分别对左子节点和右子节点进行递归。而这里等价于对children数组进行遍历。这样,可以很容易从二叉树的递归当中设计递归。
可以总结出我们的最小规模便是判断一个节点是否是目标节点,将节点压入数组当中,结束条件一:我们找到了目标节点,结束条件二:这已经是没有孩子的叶子节点了。我们在每次递归时,压入当前的节点,在不符合条件时,从最后一个弹出。当找到目标节点的时候,设置标识符。之后便一路返回,不作操作。在递归结束后便得到了目标数组。这个数组从尾部到头部便是目标节点到根节点的一条完整路径。
let outputArray:Array<DataFormat>=[];
let findFlag=false;
/**
*
* @param item 待遍历数组结构
* @param target 待查找目标节点
*/
const getPath:(item:DataFormat,target:DataFormat)=>void=
function(item:DataFormat,target:DataFormat):void{
outputArray.push(item);
if(item.name===target.name){
//找到节点后设置标识
findFlag=true;
return
}
if(item.children&&item.children.length>0){
for(let i=0;i<item.children.length;i++){
getPath(item.children[i],target);
if(findFlag){
//如果有标识则不进行多余操作,直接返回
return
}
}
//子节点遍历后没有找到便弹出其父节点
outputArray.pop();
}else if(!item.children||item.children.length===0){
//遍历到最下层后弹出子节点
outputArray.pop();
}
}
版权声明:本文为qq_21816073原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。