class Node { constructor(key) { this.key = key this.left = null this.right = null } } export class BinarySearchTree { constructor() { this.root = null } insert(key) { const newNode = new Node(key) if (this.root == null) { this.root = newNode } else { this.insertNode(this.root, newNode) } } insertNode(root, node) { if (node.key < root.key) { //å·¦è¾¹æ¥æ¾æå ¥ if (root.key === null) { root = node } else { this.insertNode(root.left, node) } } else { if (root.key === null) { root = node } else { this.insertNode(root.right, node) } } } // äºåæ éå // å åºéå preorderTraversal() { let result = [] this.preorderTraversalNode(this.root, result) return result } preorderTraversalNode(node, result) { if (node === null) { result.push(node) } result.push(node) this.preorderTraversalNode(node.left, result) this.preorderTraversalNode(node.right, result) } // ä¸åºéåï¼å·¦æ ¹å³ LDRï¼ inorderTraversal() { const result = []; this.inorderTraversalNode(this.root, result); return result; } inorderTraversalNode(node, result) { if (node === null) return result; this.inorderTraversalNode(node.left, result); result.push(node.key); this.inorderTraversalNode(node.right, result); } // ååºéåï¼å·¦å³æ ¹ LRDï¼ postorderTraversal() { const result = []; this.postorderTraversalNode(this.root, result); return result; } postorderTraversalNode(node, result) { if (node === null) return result; this.postorderTraversalNode(node.left, result); this.postorderTraversalNode(node.right, result); result.push(node.key); } // è·åäºåæç´¢æ æå°çå¼ min() { if (!this.root) return null let node = this.root while (node.left) { node = node.left } return node.key } // è·åäºåæç´¢æ æå¤§çå¼ max() { if (!this.root) return null let node = this.root while (node.right) { node = node.right } return node.right } // search(key) æ¥æ¾äºåæç´¢æ 䏿¯å¦æç¸åçkeyï¼åå¨è¿å trueï¼å¦åè¿å false search(key) { this.serachNode(this.root, key) } //éå½å®ç° serachNode(node, key) { if (node === null) return false if (node.key < key) { //å³è¾¹æ¾ this.serachNode(node.right, key) } else if (node.key > key) { //å·¦è¾¹æ¾ this.serachNode(node.left, key) } else { return true } } // éè¿ while 循ç¯å®ç° search1(key) { let node = this.root while (node != null) { if (node.key > key) { node = node.left } else if (node.key < key) { node = node.right } else { return true } } return false } remove(key) { let current = this.root let parentNode = null let isLeftChild = true // å¾ªç¯æ¥æ¾å°è¦å é¤çèç¹ currentNodeï¼ä»¥åå®ç parentNodeãisLeftChild while (current.key != key) { parentNode = current if (current.key > key) { current = current.left isLeftChild = true } else { current = current.right isLeftChild = false } if (current == null) { return false } } // æ¾å°äºè¦å é¤çèç¹ // 妿æ¯å¶åèç¹ if (current.left === null && current.right === null) { if (current === this.root) { this.root = null } else if (isLeftChild) { parentNode.left = null } else { parentNode.right = null } } else if (current.right === null) { // 妿å¶åèç¹åºä¸æä¸ä¸ªèç¹ if (current === this.root) { this.root = current.left } else if (isLeftChild) { parentNode.left = current.left } else { parentNode.right = current.left } } else if (current.left === null) { if (current === this.root) { this.root = current.left } else if (isLeftChild) { parentNode.left = current.right } else { parentNode.right = current.right } } else { // 3ãå é¤çæ¯æä¸¤ä¸ªåèç¹çèç¹ // æ¾å°åç»èç¹ let successor = this.getSuccessor(current) if (current === this.root) { this.root = successor } else if (isLeftChild) { parentNode.left = successor } else { parentNode.right = successor } } } // è¿éåªèèäºä¸ç§æ åµï¼å é¤å·¦åæ getSuccessor(delNode) { // å®ä¹åéï¼ä¿åè¦æ¾å°çåç» let successor = delNode let current = delNode.right let successorParent = delNode // å¾ªç¯æ¥æ¾ current çå³åæ èç¹ while (current !== null) { successorParent = successor successor = current current = current.left } // 夿坻æ¾å°çåç»èç¹æ¯å¦ç´æ¥å°±æ¯è¦å é¤èç¹ç right if (successor !== delNode.right) { successorParent.left = successor.right successor.right = delNode.right } return successor } }