如何將扁平陣列轉為樹形結構 實現O(n²)與O(n)時間複雜度的方案
阿新 • • 發佈:2021-12-22
/* let arr = [ { id: 1, name: '部門1', pid: 0 }, { id: 2, name: '部門2', pid: 1 }, { id: 3, name: '部門3', pid: 1 }, { id: 4, name: '部門4', pid: 3 }, { id: 5, name: '部門5', pid: 4 }, { id: 6, name: '部門6', pid: 4666 }, ] 輸出結果: [ { "id": 1, "name": "部門1", "pid": 0, "children": [ { "id": 2, "name": "部門2", "pid": 1, "children": [] }, { "id": 3, "name": "部門3", "pid": 1, "children": [ // 結果 ,,, ] } ] }, { id: 6, name: '部門6', pid: 4666 } ] */ /* 方案1 遞迴方式 先找出所有根節點,再找出所有根節點的子節點 時間複雜度: O(n²) */ const getChildren = root => { root.children = arr.filter(v => v.pid === root.id) root.children.forEach(v => getChildren(v)) } const transferTree = arr => { if (!Array.isArray(arr)) throw new Error('parameter arr must be Array.') if (arr.length === 1) return arr // 父子關係可以用map儲存 const idMap = arr.reduce((total, cur) => Object.assign(total, { [cur.id]: { ...cur, children: [] } }), {}) // 找出所有根節點 const roots = arr.filter(node => !idMap[node.pid]) // 找出根節點下面所有子節點 roots.forEach(root => getChildren(root)) return roots } /* 方案2 非遞迴方式 時間複雜度: O(n) */ const transferTree2 = arr => { if (!Array.isArray(arr)) throw new Error('parameter arr must be Array.') if (arr.length === 1) return arr const res = [] const idMap = arr.reduce((total, cur) => Object.assign(total, { [cur.id]: { ...cur, children: [] } }), {}) for (const [, node] of Object.entries(idMap)) { // 根節點 if (idMap[node.pid]) { res.push(node) continue; } // 子節點 idMap[node.pid].children.push(node) } return res } console.log(transferTree2(arr))