树形结构数据是一种常用的数据结构,它由多个节点组成,每个节点可以有多个子节点,形成树状结构。在JavaScript中,我们可以使用对象来表示树形结构数据。
1. 定义节点对象
class Node {
constructor(id, name, parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.children = [];
}
}
节点对象包含id,name,parentId和children四个属性,其中id和name表示节点的唯一标识和名称,parentId表示父节点的id,children表示子节点数组。
2. 构建树形结构
function buildTree(list) {
let map = {};
let roots = [];
for (let i = 0; i < list.length; i++) {
let node = new Node(list[i].id, list[i].name, list[i].parentId);
map[node.id] = node;
if (node.parentId === 0) {
roots.push(node);
} else {
let parent = map[node.parentId];
parent.children.push(node);
}
}
return roots;
}
buildTree函数接收一个节点数组list作为参数,遍历数组创建节点对象,并将节点对象放入map对象中以便后续查找。如果节点的parentId为0,则将该节点对象放入根节点数组roots中,否则在map对象中查找该节点的父节点,并将该节点对象放入父节点的children数组中。
3. 遍历树形结构
function traverse(node) {
console.log(node.name);
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
traverse(node.children[i]);
}
}
}
traverse函数接收一个节点对象node作为参数,首先输出该节点的名称,然后遍历该节点的children数组,递归调用traverse函数遍历子节点。
class Node {
constructor(id, name, parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.children = [];
}
}
function buildTree(list) {
let map = {};
let roots = [];
for (let i = 0; i < list.length; i++) {
let node = new Node(list[i].id, list[i].name, list[i].parentId);
map[node.id] = node;
if (node.parentId === 0) {
roots.push(node);
} else {
let parent = map[node.parentId];
parent.children.push(node);
}
}
return roots;
}
function traverse(node) {
console.log(node.name);
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
traverse(node.children[i]);
}
}
}
let list = [
{ id: 1, name: '节点1', parentId: 0 },
{ id: 2, name: '节点2', parentId: 0 },
{ id: 3, name: '节点3', parentId: 1 },
{ id: 4, name: '节点4', parentId: 1 },
{ id: 5, name: '节点5', parentId: 2 },
{ id: 6, name: '节点6', parentId: 3 },
{ id: 7, name: '节点7', parentId: 3 },
{ id: 8, name: '节点8', parentId: 5 },
{ id: 9, name: '节点9', parentId: 5 },
];
let roots = buildTree(list);
for (let i = 0; i < roots.length; i++) {
traverse(roots[i]);
}
以上代码输出结果为:
节点1
节点3
节点6
节点7
节点4
节点2
节点5
节点8
节点9