ts-ds-tool
Version:
Data structure and algorithm of TypeScript
120 lines (106 loc) • 3.22 kB
text/typescript
import { BasicBinaryTree } from "../basic-binary-tree/BasicBinaryTree";
import { BinarySearchTreeNode } from "./BinarySearchTreeNode";
export class BinarySearchTree<T= number>{
private root?: BinarySearchTreeNode<T>;
constructor(private compareKey?: keyof T){
}
get Root(){
return this.root;
}
set Root(node: BinarySearchTreeNode<T>){
this.root = node;
}
insert(value: T){
if (value === null || value === undefined){
return;
}
if (!this.root){
this.root = new BinarySearchTreeNode(value);
return this.root;
}
return this.root.insert(value, this.compareKey);
}
remove(value: T){
const node = this.find(value);
if (!node){
return false;
}
this.removeNode(node);
return true;
}
clear(){
this.Root = null;
}
/**
* 删除节点
* @param node
* @returns 删除节点的父节点
*/
protected removeNode(node: BinarySearchTreeNode<T>){
if (!node) {
return false;
}
let nodeSuccessor: BinarySearchTreeNode<T>;
let successorChild: BinarySearchTreeNode<T> = null;
if (!node.Left || !node.Right) {
nodeSuccessor = node;
} else {
nodeSuccessor = this.successor(node);
}
if (nodeSuccessor.Left) {
successorChild = nodeSuccessor.Left as BinarySearchTreeNode<T>;
} else {
successorChild = nodeSuccessor.Right as BinarySearchTreeNode<T>;
}
if (successorChild){
successorChild.parent = nodeSuccessor.parent;
}
if (!nodeSuccessor.parent) {
this.root = successorChild;
} else if (nodeSuccessor.parent.Left === nodeSuccessor) {
nodeSuccessor = this.copyNode(nodeSuccessor);
nodeSuccessor.parent.setLeft(successorChild);
} else {
nodeSuccessor = this.copyNode(nodeSuccessor);
nodeSuccessor.parent.setRight(successorChild);
}
node.setValue(nodeSuccessor.Value);
return {successorChild, nodeSuccessor};
}
private successor(node: BinarySearchTreeNode<T>) {
let nodeSuccessor = node.Right;
while (nodeSuccessor.Left) {
nodeSuccessor = nodeSuccessor.Left;
}
return nodeSuccessor as BinarySearchTreeNode<T>;
}
private copyNode(source: BinarySearchTreeNode<T>){
const node = new BinarySearchTreeNode<T>(source.Value);
// tslint:disable-next-line:forin
for (const key in source){
node[key] = source[key];
}
return node;
}
contains(value: T) {
if (!this.root){
return false;
}
return this.root.contains(value, this.compareKey);
}
find(value: T){
if (!this.root){
return null;
}
return this.root.find(value, this.compareKey);
}
getAscSeq(){
return BasicBinaryTree.inTraversal(this.root);
}
toString(){
if (!this.root){
return "";
}
return this.root.toString();
}
}