UNPKG

pisces-data-structure

Version:

164 lines (120 loc) 4.4 kB
/** * AVL树 */ import type { IAVLTreeNode, IAVLTree } from "../../../types"; import { BinarySearchTreeNode, BinarySearchTree } from "../index"; // AVL树节点类 class AVLTreeNode<T = any> extends BinarySearchTreeNode<T> implements IAVLTreeNode<T> { left: AVLTreeNode<T> | null = null; right: AVLTreeNode<T> | null = null; parent: AVLTreeNode<T> | null = null; private getHeight(): number { const _leftChildHeight = this.left ? this.left.getHeight() : 0; const _rightChildHeight = this.right ? this.right.getHeight() : 0; return Math.max(_leftChildHeight, _rightChildHeight) + 1; } public getBalanceFactor(): number { const _leftChildHeight = this.left ? this.left.getHeight() : 0; const _rightChildHeight = this.right ? this.right.getHeight() : 0; return _leftChildHeight - _rightChildHeight; } public get isBalanced(): boolean { const _balanceFactor = this.getBalanceFactor(); return _balanceFactor >= -1 && _balanceFactor <= 1; } get higherChildNode(): AVLTreeNode<T> | null { const _leftChildHeight = this.left ? this.left.getHeight() : 0; const _rightChildHeight = this.right ? this.right.getHeight() : 0; if (_leftChildHeight > _rightChildHeight) { return this.left; } else if (_rightChildHeight > _leftChildHeight) { return this.right; } else { return this.isLeftChild ? this.left : this.right; } } public rotateRight() { const _pivot = this.left!; const _isLeftChild = this.isLeftChild; const _isRightChild = this.isRightChild; _pivot.parent = this.parent; this.left = _pivot.right; if (_pivot.right) { _pivot.right.parent = this; } _pivot.right = this; this.parent = _pivot; if (_pivot.parent) { if (_isLeftChild) { _pivot.parent.left = _pivot; } else if (_isRightChild) { _pivot.parent.right = _pivot; } } return _pivot; } rotateLeft() { const _pivot = this.right!; const _isLeftChild = this.isLeftChild; const _isRightChild = this.isRightChild; _pivot.parent = this.parent; this.right = _pivot.left; if (_pivot.left) { _pivot.left.parent = this; } _pivot.left = this; this.parent = _pivot; if (_pivot.parent) { if (_isLeftChild) { _pivot.parent.left = _pivot; } else if (_isRightChild) { _pivot.parent.right = _pivot; } } return _pivot; } } // AVL数类 class AVLTree<T = any> extends BinarySearchTree<T> implements IAVLTree<T> { protected root: AVLTreeNode<T> | null = null; private rebalance(grandParent: AVLTreeNode<T>) { const _parent = grandParent.higherChildNode!; const _current = _parent.higherChildNode!; let _resultNode: AVLTreeNode<T> | null = null; if (_parent.isLeftChild) { if (_current.isLeftChild) { _resultNode = grandParent.rotateRight(); } else { _parent.rotateLeft(); _resultNode = grandParent.rotateRight(); } } else { if (_current.isLeftChild) { // RL情况 _parent.rotateRight(); _resultNode = grandParent.rotateLeft(); } else { _resultNode = grandParent.rotateLeft(); } } if (!_resultNode.parent) { this.root = _resultNode; } } protected createTreeNode(value: T): BinarySearchTreeNode<T> { return new AVLTreeNode(value); } protected checkBalance(treeNode: AVLTreeNode<T>, actionType = 'insert'): void { let _current = treeNode.parent; while (_current) { if (!_current.isBalanced) { this.rebalance(_current); if (actionType === 'insert') break; } _current = _current.parent; } } } export { AVLTreeNode, AVLTree, };