1. Array -> Tree
var arr = [
{ id: 12, parentId: 1, name: "朝阳区" },
{ id: 241, parentId: 24, name: "田林街道" },
{ id: 31, parentId: 3, name: "广州市" },
{ id: 13, parentId: 1, name: "昌平区" },
{ id: 2421, parentId: 242, name: "上海科技绿洲" },
{ id: 21, parentId: 2, name: "静安区" },
{ id: 242, parentId: 24, name: "漕河泾街道" },
{ id: 22, parentId: 2, name: "黄浦区" },
{ id: 11, parentId: 1, name: "顺义区" },
{ id: 2, parentId: 0, name: "上海市" },
{ id: 24, parentId: 2, name: "徐汇区" },
{ id: 1, parentId: 0, name: "北京市" },
{ id: 2422, parentId: 242, name: "漕河泾开发区" },
{ id: 32, parentId: 3, name: "深圳市" },
{ id: 33, parentId: 3, name: "东莞市" },
{ id: 3, parentId: 0, name: "广东省" },
];
function arrayToTreeV3(arr, root) {
return arr
.filter((item) => item.parentId === root)
.map((item) => ({ ...item, children: arrayToTreeV3(arr, item.id) }));
}
let test = arrayToTreeV3(arr, 0);
2. Tree -> Array
const treeData = [
{
id: 2,
title: "中国",
parent_id: 0,
children: [
{
id: 3,
title: "广东省",
parent_id: 2,
children: [
{
id: 4,
title: "广州市",
parent_id: 3,
children: [{ id: 5, title: "天河区", parent_id: 4 }],
},
],
},
{ id: 6, title: "湖南省", parent_id: 2 },
],
},
{ id: 1, title: "俄罗斯", parent_id: 0 },
];
function treeToList(data) {
let res = [];
const dfs = (tree) => {
tree.forEach((item) => {
if (item.children) {
dfs(item.children);
delete item.children;
}
res.push(item);
});
};
dfs(data);
return res;
}
let testarr = treeToList(treeData);
3.Tree 查找路径(id)
function parseTreePath(tree, id, path = "") {
for (let i = 0; i < tree.length; i++) {
let tempPath = path;
// 避免出现在最前面的/
tempPath = `${tempPath ? tempPath + "/ " : tempPath}${tree[i].title}`;
if (tree[i].id == id) return tempPath;
else if (tree[i].children) {
let reuslt = parseTreePath(tree[i].children, id, tempPath);
if (reuslt) return reuslt;
}
}
}
console.log(parseTreePath(treeData, 5));
4. 树的深度优先遍历
思想:访问该元素后,如果该元素存在子元素,则访问该元素的第一个子元素,如果不存在,则访问该元素的兄弟节点(即退出该函数,返回上一层函数,访问上一层中未被访问的子元素),重复此操作。
// a
// b c
//c d e f g h i
const dfs = root => {
if(!root) return;
console.log(root.val);
root.children.forEach(child => {
dfs(child)
})
}
dfs( treeData)
// a b d e f c g h i
5. 广度优先遍历
思想:访问该元素后,如果该元素存在兄弟节点,则依次访问该元素的兄弟节点,如果不存在,则访问该元素的孩子节点
// a
// b c
//c d e f g h i
const bfs = root => {
if(!root) return;
const queue = [root];
while(queue.length) {
const top = queue.shift();
console.log(top.val);
top.children.forEach(child => {
queue.push(child)
})
}
}
bfs( treeData)
// a b c d e f g h i