// å®ä¹èç¹ class Node { constructor(key, value) { this.key = key; this.value = value; this.left = null; this.right = null; this.height = 1; } } // å®ä¹AVLæ module.exports = class AVLTree { constructor() { this.root = null; this.size = 0; } // å¤æè¯¥äºåæ æ¯å¦æ¯ä¸è¯¾äºåæç´¢æ isBST() { let keys = []; this.inOrder(this.root, keys); for(let i = 1; i < keys.length; i++) { if(keys[i-1] > keys[i]) { return false; } } return true; } inOrder(node, keys) { if(node === null) return; this.inOrder(node.left, keys); keys.push(node.key); this.inOrder(node.right, keys); } // å¤æè¯¥äºåæ æ¯å¦æ¯ä¸æ£µå¹³è¡¡äºåæ ,éå½ç®æ³ isBalanced() { return this._isBalanced(this.root); } _isBalanced(node) { if(node === null) return true; let balanceFactor = this.getBalanceFactor(node); if(Math.abs(balanceFactor) > 1) return false; return this._isBalanced(node.left) && this._isBalanced(node.right); } // è·å¾èç¹nodeçé«åº¦ getHeight(node) { if(node === null) return 0; return node.height; } // è·å¾èç¹nodeç平衡å å getBalanceFactor(node) { if(node === null) return 0; return this.getHeight(node.left) - this.getHeight(node.right); } // åäºåæç´¢æ æ·»å æ°çå ç´ (key, value) add(key, value) { this.root = this._add(this.root, key, value); } // å以nodeä¸ºæ ¹çäºåæç´¢æ ä¸æå ¥å ç´ (key, value),éå½ç®æ³ // è¿åæå ¥æ°èç¹åäºåæç´¢æ çæ ¹ _add(node, key, value) { if(node === null) { this.size++; return new Node(key, value); } // 妿keyå°äºèç¹çkeyï¼åæå ¥å°èç¹çå·¦åæ ä¸ if(key < node.key) { node.left = this._add(node.left, key, value); } else if(key > node.key) { // 妿key大äºèç¹çkeyï¼åæå ¥å°èç¹çå³åæ ä¸ node.right = this._add(node.right, key, value); } else { // æ´æ°æä½ node.value = value; } // æ´æ°height node.height = 1 + Math.max(this.getHeight(node.left), this.getHeight(node.right)); // 计ç®å¹³è¡¡å å let balanceFactor = this.getBalanceFactor(node); // å¨IIç代ç 䏿·»å è°èå¹³è¡¡çæ¹æ³ if(Math.abs(balanceFactor) > 1) { console.log('unbalanced:' + balanceFactor); } return node; } // è¿å以nodeä¸ºæ ¹èç¹çäºåæç´¢æ ä¸ï¼keyæå¨èç¹ getNode(node, key) { if(node === null) return null; if(key.equals(node.key)) return node; else if(key < node.key) return this.getNode(node.left, key); else return this.getNode(node.right, key); } // 夿æ¯å¦å å«è¯¥node contains(key) { return this.getNode(this.root, key) !== null; } // æ ¹æ®keyå¼è·åèç¹ get(key) { let node = this.getNode(this.root, key); return node === null ? null : node.value; } // 设置nodeçå¼ set(key, value) { let node = this.getNode(this.root, key); return node === null ? null : node.value; } // è¿å以nodeä¸ºæ ¹çäºåæç´¢æ çæå°å¼æå¨èç¹ minimun(node) { if(node.left === null) return node; return this.minimun(node); } // å 餿以nodeä¸ºæ ¹çäºåæç´¢æ ä¸çæå°èç¹ // è¿åå é¤èç¹åæ°çäºåæç´¢æ çæ ¹ removeMin(node) { if(node.left === null) { let rightNode = node.right; node.right = null; this.size--; return rightNode; } node.left = this.removeMin(node.left); return node; } // ä»äºåæç´¢æ ä¸å é¤é®ä¸ºkeyçèç¹ remove(key) { let node = this.getNode(this.root, key); if(node !== null) { this.root = this._remove(this.root, key); return node.value; } return null; } _remove(node, key) { if(node === null) { return null; } if(key < node.key) { node.left = this._remove(node.left, key); return node; } else if(key > node.key) { node.right = this._remove(node.right, key); return node; } else { // å¾ å é¤èç¹å·¦åæ ä¸ºç©ºçæ åµ if(node.left === null) { let rightNode = node.right; node.right = null; this.size--; return rightNode; } // å¾ å é¤èç¹å³åæ ä¸ºç©ºçæ åµ if(node.right === null) { let leftNode = node.left; node.left = null; this.size--; return leftNode; } // å¾ å é¤èç¹å·¦å³åæ åä¸ä¸ºç©ºçæ åµ // æ¾å°æ¯å¾ å é¤èç¹å¤§çæå°èç¹ï¼å³å¾ å é¤èç¹å³åæ çæå°èç¹ // ç¨è¿ä¸ªèç¹æ¿æ¢å¾ å é¤èç¹çä½ç½® let successor = this.minimun(node.right); successor.right = this.removeMin(ndoe.right); successor.left = node.left; node.left = node.right = null; return successor; } } // è·åæ çå¤§å° getSize() { return this.size; } // å¤ææ æ¯å¦ä¸ºç©º isEmpty() { return this.size === 0; } }