树形结构根据节点查找某条路径(typescript)

这是节点结构,默认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版权协议,转载请附上原文出处链接和本声明。