<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小树苗</title>
</head>
<body>
<script>
class Node{
constructor(value = null, parent = null) {
this.value = value;
this.parent = parent;
this.child = [];
}
}
class SingleTree{//值不能重复
constructor(_config) {
/**
{resort}模式,下面这种情况,b会被更新为a的子节点,a会被更新为z的子节点
tree
.add('b', 'c')
.add('a', 'b')
.add('z', 'a')
*/
this.config = Object.assign({
resort: true,
}, _config);
this.db = [];
}
find(id) {
let node = null;
const main = (data, id) => {
for (let i in data) {
if (data[i].value === id) return node = data[i];
main(data[i].child, id);
}
}
main(this.db, id);
return node;
}
pickExistsNode(id) {//提取指定节点,会移除原数据
const target = this.find(id);
if (!target) return;
const parent = target.parent === null ? this.db : target.parent;
for (let i in parent) {
if (parent[i] && target.value === parent[i].value) return parent.splice(i, 1)[0];
}
}
add(pid, id) {
// <立个flag哈,不要用targetNode.parent判断>
let isRoot = false;
//如果没找到target节点,则生成一个根节点,flag置为true
const targetNode = this.find(pid) || (isRoot = true, new Node(pid));
if (id) {
const node = new Node(id, targetNode), existsNode = this.pickExistsNode(id);
//以新节点为准,提出旧节点的child
if (existsNode) node.child = node.child.concat(existsNode.child);
targetNode.child.push(node);
if (isRoot) {
this.db.push(targetNode);
}
}
return this;
}
remove(id) {
if (!this.pickExistsNode(id)) {
console.log(`${id},数据不存在`);
}
return this;
}
}
const tree = new SingleTree();
tree
.add(1, 2)
.add(2, 3)
.add(4, 1)
.add(7, 4)
.add(8, 7)
.add(9, 0)
//如果使用了重复的值,则会新开一个子节点,此时程序已经GG....
.add(9, 1)
.add(1, '??')
.remove(9)
.add(1, '??')
.remove(999)
console.log(tree.db);
</script>
</body>
</html>
小树苗
最新推荐文章于 2024-04-30 11:01:51 发布