using System; using System.Collections.Generic; using System.Text; namespace QiHe.CodeLib { public class BinarySearchTreeBase where TItem : IComparable where TTreeNode : BinaryTreeNodeBase, new() { public TTreeNode Root; private int count; public BinarySearchTreeBase() { Root = Nil; } public virtual TTreeNode Nil { get { return null; } } /// /// The number of nodes contained in the tree. /// public int Size { get { return count; } } public IEnumerable InorderTreeWalk() { foreach (TTreeNode node in InorderTreeWalk(Root)) { yield return node.Data; } } public bool Contains(TItem item) { return Search(Root, item) != Nil; } public TTreeNode Find(TItem item) { return Search(Root, item); } public void Add(TItem item) { TTreeNode node = new TTreeNode(); node.Data = item; Insert(node); } public void Remove(TItem item) { TTreeNode node = Search(Root, item); if (node != Nil) { Delete(node); } } public void Clear() { Root = Nil; count = 0; } public IEnumerable InorderTreeWalk(TTreeNode node) { if (node != Nil) { foreach (TTreeNode subnode in InorderTreeWalk(node.Left)) { yield return subnode; } yield return node; foreach (TTreeNode subnode in InorderTreeWalk(node.Right)) { yield return subnode; } } } public TTreeNode Search(TTreeNode node, TItem item) { if (node == Nil || node.Data.CompareTo(item) == 0) { return node; } if (item.CompareTo(node.Data) < 0) { return Search(node.Left, item); } else { return Search(node.Right, item); } } public TTreeNode Minimum(TTreeNode node) { if (node == Nil) return Nil; TTreeNode left = node; while (left.Left != Nil) { left = left.Left; } return left; } public TTreeNode Maximum(TTreeNode node) { if (node == Nil) return Nil; TTreeNode right = node; while (right.Right != Nil) { right = right.Right; } return right; } protected TTreeNode Successor(TTreeNode node) { if (node.Right != Nil) { return Minimum(node.Right); } TTreeNode parent = node.Parent; while (parent != Nil && node == parent.Right) { node = parent; parent = parent.Parent; } return parent; } protected TTreeNode Predecessor(TTreeNode node) { if (node.Left != Nil) { return Maximum(node.Left); } TTreeNode parent = node.Parent; while (parent != Nil && node == parent.Left) { node = parent; parent = parent.Parent; } return parent; } /// /// Rebalance the tree by rotating the nodes to the left. /// protected void RotateLeft(TTreeNode x) { // pushing node x down and to the Left to balance the tree. x's Right child (y) // replaces x (since y > x), and y's Left child becomes x's Right child // (since it's < y but > x). TTreeNode y = x.Right; // Turn y's left subtree into x's right subtree x.Right = y.Left; // modify parents if (y.Left != Nil) { y.Left.Parent = x; } if (y != Nil) { y.Parent = x.Parent; } if (x.Parent != Nil) { // determine which side of it's Parent x was on if (x.IsLeftChild) { x.Parent.Left = y; } else { x.Parent.Right = y; } } else { // at rbTree, set it to y Root = y; } // link x and y // put x on y's Left y.Left = x; if (x != Nil) { x.Parent = y; } } /// /// Rebalance the tree by rotating the nodes to the right. /// protected void RotateRight(TTreeNode x) { // pushing node x down and to the Right to balance the tree. x's Left child (y) // replaces x (since x < y), and y's Right child becomes x's Left child // (since it's < x but > y). // get x's Left node, this becomes y TTreeNode y = x.Left; // y's Right child becomes x's Left child x.Left = y.Right; // modify parents if (y.Right != Nil) { y.Right.Parent = x; } if (y != Nil) { y.Parent = x.Parent; } // Nil=rbTree, could also have used rbTree if (x.Parent != Nil) { // determine which side of it's Parent x was on if (x.IsRightChild) { x.Parent.Right = y; } else { x.Parent.Left = y; } } else { // at rbTree, set it to y Root = y; } // link x and y // put x on y's Right y.Right = x; if (x != Nil) { x.Parent = y; } } public virtual void Insert(TTreeNode node) { TTreeNode parent = Nil; TTreeNode current = Root; while (current != Nil) { parent = current; if (node.Data.CompareTo(current.Data) < 0) { current = current.Left; } else { current = current.Right; } } node.Parent = parent; if (parent == Nil) { Root = node; } else { if (node.Data.CompareTo(parent.Data) < 0) { parent.Left = node; } else { parent.Right = node; } } count++; } public virtual TTreeNode Delete(TTreeNode node) { TTreeNode tobeDeleted; if (node.Left == Nil || node.Right == Nil) { tobeDeleted = node; } else { tobeDeleted = Successor(node); } TTreeNode childNode; if (tobeDeleted.Left != Nil) { childNode = tobeDeleted.Left; } else { childNode = tobeDeleted.Right; } if (childNode != Nil) { childNode.Parent = tobeDeleted.Parent; } TTreeNode parent = tobeDeleted.Parent; if (parent == Nil) { Root = childNode; } else { if (tobeDeleted.IsLeftChild) { parent.Left = childNode; } else { parent.Right = childNode; } } if (tobeDeleted != node) { node.Data = tobeDeleted.Data; } count--; return tobeDeleted; } } }