/// <summary> /// Initializes a new instance of the <see cref="SplayTreeNode{T}"/> class. /// Constructor. /// </summary> /// <param name="data"> /// Values for the node. /// </param> /// <param name="left"> /// Left child node. /// </param> /// <param name="right"> /// Right child node. /// </param> public SplayTreeNode(List <T> data, SplayTreeNode <T> left, SplayTreeNode <T> right) { this.Values = data; NodeList <T> children = new NodeList <T>(2); children[0] = left; children[1] = right; this.Neighbors = children; if (left.Height > right.Height) { this._height = left.Height + 1; } else { this._height = right.Height + 1; } }
/// <summary> /// Adds element to the tree. /// </summary> /// <param name="data"> /// Element to be added. /// </param> public override void Add(T data) { var dataList = new List <T>(1) { data }; var node = new SplayTreeNode <T>(dataList); SplayTreeNode <T> current = this._root, parent = null; int result; while (current != null) { result = this._comparer.Compare(current.Values[0], data); if (result > 0) { parent = current; current = current.Left; } else { parent = current; current = current.Right; } } if (parent == null) { this._root = node; } else { result = this._comparer.Compare(parent.Values[0], data); if (result > 0) { parent.Left = node; } else { parent.Right = node; } } node.Parent = parent; this.Splay(node); }
/// <summary> /// Indicates whether tree contains element. /// </summary> /// <param name="data"> /// Element to be searched. /// </param> /// <returns> /// </returns> public override SearchResult Contains(T data) { SearchResult searchResult; searchResult.SearchPath = new List <int>(); searchResult.NodesVisited = 0; SplayTreeNode <T> lastVisited = null; SplayTreeNode <T> current = this._root; while (current != null) { searchResult.NodesVisited++; int result = this._comparer.Compare(current.Values[0], data); if (result == 0) { this.Splay(current); if (searchResult.SearchPath != null) { searchResult.SearchPath.Clear(); searchResult.SearchPath = new List <int>(); } return(searchResult); } if (result > 0) { lastVisited = current; current = current.Left; searchResult.SearchPath.Add(0); } else { lastVisited = current; current = current.Right; searchResult.SearchPath.Add(1); } } this.Splay(lastVisited); searchResult.SearchPath = null; return(searchResult); }
/// <summary> /// Initializes a new instance of the <see cref="SplayTree{T}"/> class. /// Basic constructor. /// </summary> public SplayTree() { this._root = null; }
/// <summary> /// Performs Splay operation on input node. /// </summary> /// <param name="node"> /// Node to be splayed. /// </param> public void Splay(SplayTreeNode <T> node) { if (this._root == null || node == null) { return; } SplayTreeNode <T> current = this._root; SplayTreeNode <T> parent = null; while (current != node) { if (current == null || current.Neighbors == null) { return; } int result = this._comparer.Compare(current.Values[0], node.Values[0]); if (result > 0) { if (current.Left != null) { parent = current; current = (SplayTreeNode <T>)current.Left; } } else { if (current.Right != null) { parent = current; current = (SplayTreeNode <T>)current.Right; } } } if (parent == null) { return; } // ZIG if (parent.Left == current) { parent.Balance(true); } // ZAG else { parent.Balance(false); } while (current.Parent != null) { current = (SplayTreeNode <T>)current.Parent; } this._root = current; if (this._root != node) { this.Splay(node); } else if (this._root != null) { this._root.UpdateHeight(); } }
/// <summary> /// Removes element from the tree. /// </summary> /// <param name="data"> /// Element to be removed. /// </param> /// <returns> /// The remove. /// </returns> public override bool Remove(T data) { if (this._root == null) { return(false); } SplayTreeNode <T> current = this._root, parent = null; int result = this._comparer.Compare(current.Values[0], data); while (result != 0) { if (result > 0) { parent = current; current = current.Left; } else { parent = current; current = current.Right; } if (current == null) { this.Splay(parent); return(false); } result = this._comparer.Compare(current.Values[0], data); } if (current.Right == null) { if (parent == null) { if (current.Left != null) { current.Left.Parent = parent; } this._root = current.Left; } else { result = this._comparer.Compare(parent.Values[0], current.Values[0]); if (result > 0) { if (current.Left != null) { current.Left.Parent = parent; } parent.Left = current.Left; } else { if (current.Right != null) { current.Right.Parent = parent; } parent.Right = current.Right; } } } else if (current.Right.Left == null) { current.Right.Left = current.Left; if (current.Left != null) { current.Left.Parent = current.Right; } if (parent == null) { if (current.Right != null) { current.Right.Parent = parent; } this._root = current.Right; } else { result = this._comparer.Compare(parent.Values[0], current.Values[0]); if (result > 0) { if (current.Right != null) { current.Right.Parent = parent; } parent.Left = current.Right; } else { if (current.Right != null) { current.Right.Parent = parent; } parent.Right = current.Right; } } } else { SplayTreeNode <T> leftMost = current.Right, lmParent = current; while (leftMost.Left != null) { lmParent = leftMost; leftMost = lmParent.Left; } lmParent.Left = leftMost.Right; leftMost.Left = current.Left; leftMost.Right = current.Right; if (lmParent.Left != null) { lmParent.Left.Parent = leftMost; } if (leftMost.Right != null) { leftMost.Right.Parent = lmParent; } if (current.Left != null) { current.Left.Parent = leftMost; } if (current.Right != null) { current.Right.Parent = leftMost; } if (parent == null) { leftMost.Parent = parent; this._root = leftMost; } else { result = this._comparer.Compare(parent.Values[0], current.Values[0]); if (result > 0) { leftMost.Parent = parent; parent.Left = leftMost; } else { leftMost.Parent = parent; parent.Right = leftMost; } } } if (current != null) { this.Splay((SplayTreeNode <T>)current.Parent); } current.Parent = current.Left = current.Right = null; return(true); }
/// <summary> /// Clears nodes of the tree. /// </summary> public override void Clear() { this._root = null; }
/// <summary> /// Performs left or right rotation. /// </summary> /// <param name="leftBalance"> /// Indicates whether perform left rotation. /// </param> public void Balance(bool leftBalance) { if (leftBalance) { // right rotation SplayTreeNode <T> z = this; SplayTreeNode <T> y = this.Left; SplayTreeNode <T> a = this.Left.Left; SplayTreeNode <T> b = this.Left.Right; SplayTreeNode <T> c = this.Right; bool zIsleftNode = false; if (z.Parent != null && ((SplayTreeNode <T>)z.Parent).Left == this) { zIsleftNode = true; } z.Left = b; if (b != null) { b.Parent = z; } y.Right = z; if (y != null) { y.Parent = z.Parent; if (y.Parent != null) { if (zIsleftNode) { ((SplayTreeNode <T>)y.Parent).Left = y; } else { ((SplayTreeNode <T>)y.Parent).Right = y; } } } z.Parent = y; } else { // left rotation SplayTreeNode <T> z = this; SplayTreeNode <T> y = this.Right; SplayTreeNode <T> a = this.Left; SplayTreeNode <T> b = this.Right.Left; SplayTreeNode <T> c = this.Right.Right; bool zIsleftNode = false; if (z.Parent != null && ((SplayTreeNode <T>)z.Parent).Left == this) { zIsleftNode = true; } z.Right = b; if (b != null) { b.Parent = z; } y.Left = z; if (y != null) { y.Parent = z.Parent; if (y.Parent != null) { if (zIsleftNode) { ((SplayTreeNode <T>)y.Parent).Left = y; } else { ((SplayTreeNode <T>)y.Parent).Right = y; } } } z.Parent = y; } }
/// <summary> /// Balances node. /// </summary> /// <returns> /// The balance. /// </returns> public bool Balance() { this.UpdateHeight(); int leftHeight = 0; int rightHeight = 0; if (this.Left != null) { leftHeight = this.Left.Height; } if (this.Right != null) { rightHeight = this.Right.Height; } if (leftHeight - rightHeight > 1) { // right rotation SplayTreeNode <T> z = this; SplayTreeNode <T> y = this.Left; SplayTreeNode <T> a = this.Left.Left; SplayTreeNode <T> b = this.Left.Right; SplayTreeNode <T> c = this.Right; bool zIsleftNode = false; if (z.Parent != null && ((SplayTreeNode <T>)z.Parent).Left == this) { zIsleftNode = true; } z.Left = b; if (b != null) { b.Parent = z; } y.Right = z; if (y != null) { y.Parent = z.Parent; if (y.Parent != null) { if (zIsleftNode) { ((SplayTreeNode <T>)y.Parent).Left = y; } else { ((SplayTreeNode <T>)y.Parent).Right = y; } } } z.Parent = y; return(true); } else if (rightHeight - leftHeight > 1) { // left rotation SplayTreeNode <T> z = this; SplayTreeNode <T> y = this.Right; SplayTreeNode <T> a = this.Left; SplayTreeNode <T> b = this.Right.Left; SplayTreeNode <T> c = this.Right.Right; bool zIsleftNode = false; if (z.Parent != null && ((SplayTreeNode <T>)z.Parent).Left == this) { zIsleftNode = true; } z.Right = b; if (b != null) { b.Parent = z; } y.Left = z; if (y != null) { y.Parent = z.Parent; if (y.Parent != null) { if (zIsleftNode) { ((SplayTreeNode <T>)y.Parent).Left = y; } else { ((SplayTreeNode <T>)y.Parent).Right = y; } } } z.Parent = y; return(true); } bool balanced = false; if (this.Left != null && this.Left.Balance()) { balanced = true; } if (this.Right != null && this.Right.Balance()) { balanced = true; } return(balanced); }