@drozdik.m/avl-tree
Version:
Classic implementation of AVL tree with improvements like efficient search of nth item and iterator.
133 lines (112 loc) • 3.78 kB
text/typescript
import { IBidirectionalIterator } from "@drozdik.m/common-interfaces/IBidirectionalIterator";
import { AVLTreeNode } from "./AVLTreeNode";
export class AVLTreeIterator<T> implements IBidirectionalIterator<T>
{
//--------------------------------------------------
//----------VARIABLE--------------------------------
//-------------------------------------------------
private current: AVLTreeNode<T> = null;
//--------------------------------------------------
//----------CONSTRUCTOR-----------------------------
//--------------------------------------------------
constructor(node: AVLTreeNode<T>)
{
this.current = node;
}
//--------------------------------------------------
//----------VALUE-----------------------------------
//--------------------------------------------------
Value(): T
{
if (!this.HasValue())
return null;
return this.current.value;
}
HasValue(): boolean
{
return this.current != null;
}
//--------------------------------------------------
//----------MOVE------------------------------------
//--------------------------------------------------
Previous(): void
{
this.current = this.Predecessor(this.current);
}
Next(): void
{
this.current = this.Successor(this.current);
}
/**
* Returns predecessor node to this node
* @param node Current node
*/
protected Predecessor(node: AVLTreeNode<T>): AVLTreeNode<T>
{
//Node has left child
if (node.left != null)
return this.FindMaxRec(node.left);
//Climb until pop from left
let parentNode = node.parent;
while (parentNode != null && node == parentNode.left)
{
node = parentNode;
parentNode = parentNode.parent;
}
return parentNode;
}
/**
* Returns successor node to this node
* @param node Current node
*/
protected Successor(node: AVLTreeNode<T>): AVLTreeNode<T>
{
//Node has right child
if (node.right != null)
return this.FindMinRec(node.right);
//Climb until pop from right
let parentNode = node.parent;
while (parentNode != null && node == parentNode.right)
{
node = parentNode;
parentNode = parentNode.parent;
}
return parentNode;
}
//--------------------------------------------------
//----------MIN-MAX---------------------------------
//--------------------------------------------------
protected FindMinRec(node: AVLTreeNode<T>): AVLTreeNode<T>
{
//Node is null
if (node == null)
return null;
//We are at the most left
if (node.left == null)
return node;
//Go deeper 0===3 (lil joke heh)
return this.FindMinRec(node.left);
}
protected FindMaxRec(node: AVLTreeNode<T>): AVLTreeNode<T>
{
//Node is null
if (node == null)
return null;
//We are at the most right
if (node.right == null)
return node;
//Go deeper
return this.FindMaxRec(node.right);
}
//--------------------------------------------------
//----------OTHERS----------------------------------
//--------------------------------------------------
/**
* Returns currently selected node. Do not use unless you know what you are doing!
* @returns Current node
*/
GetCurrentNode(): AVLTreeNode<T>
{
return this.current;
}
}