常用的递归总结

614 阅读1分钟
  • 在写递归之前,一定要搞清楚两点: 入参和返回值,同时一定要有基线条件,即不满足条件的话要结束操作

树形结构

const bt = [
    {
        id: 1,
        name: 'A',
        type: 'admin',
        children: [
            {
                id: 2,
                name: 'A_1',
                type: 'admin',
                children: [
                    {
                        id: 3,
                        name: 'A_1_1',
                        type: 'user',
                    }
                ]
            },
            {
                id: 4,
                name: 'A_2',
                type: 'user',
            },
        ]
    },
    {
        id: 5,
        name: 'B',
        type: 'admin',
        children: [
            {
                id: 6, 
                name: 'B_1',
                type: 'user',
                children: [
                    {
                        id: 7,
                        name: 'B_1_1',
                        type: 'admin',
                    }
                ]
            }
        ]
    }
]
module.exports = bt

常用的几种递归方法

1.深度优先遍历
 const tree = (root, id) => {
     if (!root || !root.length)  return

     for (const item of root) {
         if (id === item.id){
             return item
         }
         const find = tree(item.children, id)
         if (find) return find
     }
 }
2.广度优先遍历
 const tree = (root, id) => {
     if (!root || !root.length)  return

     for (const item of root) {
         if (id === item.id){
             return item
         }
     }

     const childrens = root.reduce((total, current) => {
         return total.concat(current.children || [])
     },[])

    return tree(childrens, id)
 }

3.打平树形结构
// 第一种
const flatten = (tree) => {
    let list = []
    tree.forEach(node => {
        const {children, ...obj} = node
        list.push(obj)
        if (children && children.length){
            const tempList = flatt(children)
            list.push(...tempList)
        }
    })
    return list
}

// 第二种
const flatten = (tree) => {
     return (tree|| [ ]).reduce((total, current) => {
        const {children, ...obj} = current
        return total.concat(obj, flatten(children))
     }, [])
}
4.根据id获取父节点

const parentIds = (root, id, parentIdsList = []) => {
    if (!root || !root.length)  return
    for (const node of root) {
        if(node.id === id){
            return parentIdsList
        }
        const find = parentIds(node.children, id, [...parentIdsList, node.id])
        if (find) return find
    }
}

5.树形结构 结构处所有人
const flattenUser = (root) => {
    if (!root || !root.length)  return
    const list = []
    root.forEach(node => {
        const { children, type, ...obj } = node
        if (type === 'user'){
            list.push(obj)
        }
        if (children && children.length){
            const tempList = flattenUser(children)
            list.push(...tempList)
        }
    })
    return list
}
6.过滤掉所有的用户
const formatTree = (root) => {
    return (root || []).filter(node => node.type === 'admin').map(node => {
        const { children } = node
        return {
            ...node,
            children: formatTree(children)
        }
    })
}