class TreeNode<T> {
data: T;
children: TreeNode<T>[];
constructor(data: T) {
this.data = data;
this.children = [];
}
addChild(child: TreeNode<T>) {
this.children.push(child);
}
removeChild(childToRemove: TreeNode<T>) {
this.children = this.children.filter(child => child!== childToRemove);
}
}
class Tree<T> {
root: TreeNode<T> | null;
constructor() {
this.root = null;
}
setRoot(data: T) {
this.root = new TreeNode(data);
}
addNode(parentData: T, childData: T) {
if (!this.root) {
throw new Error('Tree has no root');
}
const queue: TreeNode<T>[] = [this.root];
while (queue.length > 0) {
const current = queue.shift()!;
if (current.data === parentData) {
const newChild = new TreeNode(childData);
current.addChild(newChild);
return;
}
queue.push(...current.children);
}
throw new Error('Parent node not found');
}
removeNode(nodeData: T) {
if (!this.root) {
throw new Error('Tree has no root');
}
const queue: TreeNode<T>[] = [this.root];
const parents: TreeNode<T>[] = [null as unknown as TreeNode<T>];
while (queue.length > 0) {
const current = queue.shift()!;
const parent = parents.shift()!;
if (current.data === nodeData) {
if (parent) {
parent.removeChild(current);
} else {
this.root = null;
}
return;
}
queue.push(...current.children);
parents.push(...new Array(current.children.length).fill(current));
}
throw new Error('Node not found');
}
}
泛型在其中提高代码可复用性和类型安全性的解释
- 可复用性:
- 通过使用泛型
T
,我们可以创建适用于不同数据类型的树形结构。例如,我们可以创建一个 Tree<number>
用于管理数字类型的数据节点,也可以创建 Tree<string>
用于管理字符串类型的数据节点。这使得代码可以在多种场景下复用,而不需要为每种数据类型都编写一套独立的树形结构代码。
- 类型安全性:
- 在编译阶段,TypeScript 基于泛型
T
进行类型检查。比如,当我们创建 Tree<number>
时,编译器会确保 addNode
方法中传入的 parentData
和 childData
都是 number
类型。如果传入了其他类型,编译器会报错,这有助于在开发阶段发现类型相关的错误,提高代码的健壮性。