public void DeleteLeaf(IBinaryTreeNode v) { if (!IsLeaf(v)) { throw new ArgumentException("Node is not a leaf"); } if (IsRoot(v)) { SetRoot(null); return; } if (((BinaryTreeNode)v).Parent.RightChild == v) { ((BinaryTreeNode)v).Parent.RightChild = null; } else if (((BinaryTreeNode)v).Parent.LeftChild == v) { ((BinaryTreeNode)v).Parent.LeftChild = null; } else { throw new Exception("Tree messed up"); } }
internal BinaryTree(IBinaryTreeNode <T> root, int nodeCount, int depth, BinaryTreeType type) { Root = root; NodeCount = nodeCount; Depth = depth; Type = type; }
public static IBinaryTreeNode <TItem> Node <TItem>( TItem item, IBinaryTreeNode <TItem> left, IBinaryTreeNode <TItem> right) { return(new BinaryTreeNode <TItem>(item, left, right)); }
private IBinaryTreeNode <T> FindWithParent(T item, out IBinaryTreeNode <T> parent) { IBinaryTreeNode <T> current = _head; parent = null; while (current != null) { var res = current.CompareTo(item); if (res > 0) { parent = current; current = current.Left; } else if (res < 0) { parent = current; current = current.Right; } else { break; } } return(current); }
/// <summary> /// Applies rebalances after inserts /// </summary> /// <param name="node">Newly isnerted node</param> private void RebalanceAfterInsert(IBinaryTreeNode <TKey, TValue> node) { IBinaryTreeNode <TKey, TValue> current = node.Parent; while (current != null) { long balance = current.GetBalance(); switch (balance) { case -2: case 2: this.Rebalance(current, balance); break; case -1: case 0: case 1: //Balanced break; default: throw new InvalidOperationException("Illegal AVL Tree state"); } current = current.Parent; } }
private static void FormatBinaryTreeNode(IBinaryTreeNode node, StringBuilder sb, string prefix, int level) { sb.Append(" "); for (int i = 0; i < level; i++) { sb.Append(" "); } if (!IsNullOrEmpty(prefix)) { sb.AppendFormat("{0}: ", prefix); } if (node == null) { sb.Append("(null)\r\n"); } else { sb.AppendFormat("{0}\r\n", Value(node.Value)); if (node.Left != null || node.Right != null) { FormatBinaryTreeNode(node.Right, sb, "RIGHT", level + 1); FormatBinaryTreeNode(node.Left, sb, "LEFT", level + 1); } } }
public ITraversableTreeNode <T>?Transform <T>(IBinaryTreeNode <T>?root) { if (root == null) { return(null); } ITraversableTreeNode <T> newNode = new TreeNode <T>(root.Value); var leftSubTree = Transform(root.Left); if (leftSubTree != null) { newNode.Children.Add(leftSubTree); } var rightSubTree = Transform(root.Right); if (rightSubTree != null) { newNode.Children.Add(rightSubTree); } return(newNode); }
/// <summary> /// Removes the key-value pair at the given index /// </summary> /// <param name="index">Index</param> public void RemoveAt(int index) { IBinaryTreeNode <TKey, TValue> node = this.MoveToIndex(index); int c = node.Parent != null?this._comparer.Compare(node.Key, node.Parent.Key) : 0; this.RemoveNode(node, c); }
/// <summary> /// Isolates a Node from the tree by setting its parent and child links to be null /// </summary> /// <typeparam name="TKey">Key Type</typeparam> /// <typeparam name="TValue">Valye Type</typeparam> /// <param name="node">Node</param> /// <returns></returns> internal static IBinaryTreeNode <TKey, TValue> Isolate <TKey, TValue>(this IBinaryTreeNode <TKey, TValue> node) { node.Parent = null; node.LeftChild = null; node.RightChild = null; return(node); }
public IBinaryTreeNode <T> InsertAfter(T value, IBinaryTreeNode <T> node) { this.EnsureNewValue(value); this.EnsureCurrentNode(node); var pivotNode = ( Node )node; var leftmostNode = (pivotNode.Right != null) ? pivotNode.Right.GetLeftmost() : null; var oldRootNode = m_rootNode; var parentNode = leftmostNode ?? pivotNode; var newNode = this.CreateNode(value); if (newNode == null) { throw new InvalidOperationException("A node was not created."); } if (leftmostNode != null) { parentNode.Left = newNode; } else { parentNode.Right = newNode; } newNode.Parent = parentNode; this.BalanceUp(parentNode); this.SetRootNodeColor(); this.OnPostInsert(newNode, oldRootNode); return(newNode); }
/// <summary> /// Internal method for searching a <paramref name="data"/> in subtree <paramref name="node"/> /// </summary> /// <param name="node">Subtree where to search</param> /// <param name="data">A value to search</param> /// <returns><see langword="true"/> if <paramref name="data"/> exists in subtree</returns> private bool InternalContains(IBinaryTreeNode <T> node, T data) { while (true) { if (ReferenceEquals(node, null)) { return(false); } switch (node.Data.CompareTo(data)) { case 0: return(true); case 1: node = node.Left; continue; default: node = node.Right; break; } } }
public static BinaryTreeNodeSaver <T> GetTreeSaverNode <T>(IBinaryTreeNode <T> Root, ref int MaxOffset, ref T MaxData, List <BinaryTreeNodeSaver <T> > Result = null) { var Res = new BinaryTreeNodeSaver <T>(Root); Result?.Add(Res); List <BinaryTreeNodeSaver <T> > Saver = new List <BinaryTreeNodeSaver <T> >(); Saver.Add(Res); List <BinaryTreeNodeSaver <T> > Buf = new List <BinaryTreeNodeSaver <T> >(); //Res.Update(Buf, ref MaxOffset, ref MaxData); do { foreach (var v in Saver) { v.Update(Buf, ref MaxOffset, ref MaxData); } Result.AddRange(Buf); var SwapBuf = Saver; Saver = Buf; Buf = SwapBuf; Buf.Clear(); } while(Saver.Count != 0); var id = Result.IndexOf(Result.Last(x => !x.IsLeaf)) + 1; Result.RemoveRange(id, Result.Count - id); return(Res); }
private IBinaryTreeNode <T> AddNodeToSearchTree(IBinaryTreeNode <T> root, IBinaryTreeNode <T> node) { if (node == null && root == null) { return(null); } if (node == null) { return(root); } if (root == null || root.Value == null) { return(node); } var compareResult = node.Value.CompareTo(root.Value); if (compareResult == 0) { return(root); } node.Parent = root; if (compareResult < 0) { node.Type = BinaryTreeNodeType.Left; root.Left = AddNodeToSearchTree(root.Left, node); } else { node.Type = BinaryTreeNodeType.Right; root.Right = AddNodeToSearchTree(root.Right, node); } return(root); }
/// <summary> /// Gets/Sets the value for a key /// </summary> /// <param name="key">Key</param> /// <returns>Returns the value associated with the key</returns> /// <exception cref="KeyNotFoundException">Thrown if the key doesn't exist</exception> public TValue this[TKey key] { get { IBinaryTreeNode <TKey, TValue> n = this.Find(key); if (n != null) { return(n.Value); } throw new KeyNotFoundException(); } set { bool created = false; IBinaryTreeNode <TKey, TValue> n = this.MoveToNode(key, out created); if (n != null) { n.Value = value; } else { throw new KeyNotFoundException(); } } }
protected IBinaryTreeNode <ValueType> Balance(IBinaryTreeNode <ValueType> node) { int bf = GetBalanceFactor(node); if (bf >= 2) { int bfL = GetBalanceFactor(node.leftChild); if (bfL >= 0) { return(RotateLL(node)); } else { return(RotateLR(node)); } } else if (bf <= -2) { int bfR = GetBalanceFactor(node.rightChild); if (bfR <= 0) { return(RotateRR(node)); } else { return(RotateRL(node)); } } else { return(node); } }
public IBinaryTree <T> BuildTree(List <T> nodeValues, BinaryTreeType type) { if (nodeValues == null || nodeValues.Count == 0) { return(null); } var nodes = new List <IBinaryTreeNode <T> >(); var depth = 0; foreach (var value in nodeValues) { nodes.Add(_nodeProvider.GetBinaryTreeNode(value)); } IBinaryTreeNode <T> root = null; switch (type) { case BinaryTreeType.Complete: { root = BuildCompleteTree(nodes); break; } case BinaryTreeType.Search: { root = BuildSearchTree(nodes); break; } } root.Type = BinaryTreeNodeType.Root; GetDepth(root, ref depth); return(new BinaryTree <T>(root, nodes.Count, depth, type)); }
/// <summary> /// Creates a new Binary Tree Node /// </summary> /// <param name="parent">Parent</param> /// <param name="key">Key</param> /// <param name="value">Value</param> public BinaryTreeNode(IBinaryTreeNode <TKey, TValue> parent, TKey key, TValue value) { this.Parent = parent; this.Key = key; this.Value = value; this.Size = 1; }
public void Remove(IBinaryTreeNode <TItem> node, IBinaryTreeNode <TItem> parent) { if (node.Item.CompareTo(Item) < 0) { LeftNode?.Remove(node, this); } else if (node.Item.CompareTo(Item) > 0) { RightNode?.Remove(node, this); } else { if (LeftNode != null && RightNode != null) { parent.RightNode = MinItem; } else if (parent.LeftNode == this) { parent.LeftNode = LeftNode ?? RightNode; } else if (parent.RightNode == this) { parent.RightNode = LeftNode ?? RightNode; } } }
public void Add(IBinaryTreeNode <TItem> node) { if (Item.CompareTo(node.Item) > 0) { if (LeftNode == null) { LeftNode = node; } else { LeftNode.Add(node); } } else if (Item.CompareTo(node.Item) < 0) { if (RightNode == null) { RightNode = node; } else { RightNode.Add(node); } } }
/// <summary> /// Rebalances a right subtree /// </summary> /// <param name="nodes">Nodes</param> /// <param name="start">Range start</param> /// <param name="end">Range end</param> /// <returns></returns> private IBinaryTreeNode <TKey, TValue> RebalanceRightSubtree(IBinaryTreeNode <TKey, TValue>[] nodes, int start, int end) { if (start > end) { return(null); } if (end == start) { return(nodes[start]); } if (end - start == 1) { IBinaryTreeNode <TKey, TValue> root = nodes[start]; root.RightChild = nodes[end]; return(root); } else if (end - start == 2) { IBinaryTreeNode <TKey, TValue> root = nodes[start + 1]; root.LeftChild = nodes[start]; root.RightChild = nodes[end]; return(root); } else { //Rebuild the tree int median = start + ((end - start) / 2); //Console.WriteLine("m = " + median); IBinaryTreeNode <TKey, TValue> root = nodes[median]; root.LeftChild = this.RebalanceLeftSubtree(nodes, start, median - 1); root.RightChild = this.RebalanceRightSubtree(nodes, median + 1, end); return(root); } }
private static IEnumerable <Tuple <IBinaryTreeNode, TLevel> > LevelOrderTraverse <TLevel>( IBinaryTreeNode partialroot, TLevel seed, Func <TLevel, IBinaryTreeNode, TLevel> leftlevelfunc, Func <TLevel, IBinaryTreeNode, TLevel> rightlevelfunc) { var queue = new Queue <Tuple <IBinaryTreeNode, TLevel> >(); queue.Enqueue(new Tuple <IBinaryTreeNode, TLevel>(partialroot, seed)); while (queue.Count > 0) { var current = queue.Dequeue(); if (!SentinelEx.EqualNull(current.Item1.LeftChild)) { queue.Enqueue(new Tuple <IBinaryTreeNode, TLevel>(current.Item1.LeftChild, leftlevelfunc == null ? current.Item2 : leftlevelfunc(current.Item2, partialroot))); } if (!SentinelEx.EqualNull(current.Item1.RightChild)) { queue.Enqueue(new Tuple <IBinaryTreeNode, TLevel>(current.Item1.RightChild, rightlevelfunc == null ? current.Item2 : rightlevelfunc(current.Item2, partialroot))); } yield return(current); } }
public bool TryGetKey(TKey key, out TKey actualKey) { ITree <IBinaryTreeNode <TKey, TValue>, TKey, TValue> tree; int hash = this._hashFunc(key); if (this._dict.TryGetValue(hash, out tree)) { IBinaryTreeNode <TKey, TValue> node = tree.Find(key); if (node == null) { actualKey = default(TKey); return(false); } else { actualKey = node.Key; return(true); } } else { actualKey = default(TKey); return(false); } }
public static int GetDegree(this IBinaryTreeNode node) { Contract.Requires <ArgumentNullException>(node != null); Contract.Ensures(Contract.Result <int>() >= 0 && Contract.Result <int>() <= 2); if (SentinelEx.NotEqualNull(node.LeftChild)) { if (SentinelEx.NotEqualNull(node.RightChild)) { return(2); } else { return(1); } } else if (SentinelEx.NotEqualNull(node.RightChild)) { return(1); } else { return(0); } }
/// <summary> /// Finds a Node based on the key /// </summary> /// <param name="key">Key</param> /// <returns>Node associated with the given Key or null if the key is not present in the tree</returns> public virtual IBinaryTreeNode <TKey, TValue> Find(TKey key) { if (this.Root == null) { return(null); } //Iteratively binary search for the key IBinaryTreeNode <TKey, TValue> current = this.Root; do { int c = this._comparer.Compare(key, current.Key); if (c < 0) { current = current.LeftChild; } else if (c > 0) { current = current.RightChild; } else { //If we find a match on the key then return it return(current); } } while (current != null); return(null); }
public static IEnumerable <IBinaryTreeNode> TraverseSubtree(this IBinaryTreeNode partialroot, TraverseOrder order = TraverseOrder.InOrder) { Contract.Requires <ArgumentNullException>(partialroot != null); Contract.Ensures(Contract.Result <IEnumerable <IBinaryTreeNode> >() != null); return(partialroot.TraverseSubtree <object>(null, null, null, order).Select(res => res.Item1)); }
private IEnumerable <T> InternalPreorder(IBinaryTreeNode <T> node) { var list = new List <T>(); var stack = new Stack <IBinaryTreeNode <T> >(); stack.Push(node); while (stack.Count > 0) { var cur = stack.Pop(); list.Add(cur.Data); if (cur.Right != null) { stack.Push(cur.Right); } if (cur.Left != null) { stack.Push(cur.Left); } } return(list); }
public static void BreadthFirstSearch <T>(IBinaryTreeNode <T> node, Action <int, T> output) where T : IBinaryTreeNode <T> { Queue <IBinaryTreeNode <T> > next = new Queue <IBinaryTreeNode <T> >(); next.Enqueue(node); int level = 0; do { Queue <IBinaryTreeNode <T> > current = next; next = new Queue <IBinaryTreeNode <T> >(); while (current.TryDequeue(out IBinaryTreeNode <T> item)) { output(level, item.Value); if (item.Left != null) { next.Enqueue(item.Left); } if (item.Right != null) { next.Enqueue(item.Right); } } } while (next.Count > 0); }
/// <summary> /// Finds the two values nearest to the search value, one above and one below. /// If an exact match is found, that value is returned in both tuple positions. /// </summary> /// <param name="searchFor">The search for.</param> /// <returns></returns> /// <remarks></remarks> public Tuple<TValue, TValue> FindNearestValues(TValue searchFor) { TValue left = default(TValue); TValue right = default(TValue); IBinaryTreeNode<TNode, TValue> currentNode = _root; while (true) { int compareResult = searchFor.CompareTo(currentNode.Value); if (compareResult == 0) { return new Tuple<TValue, TValue>(currentNode.Value, currentNode.Value); } if (compareResult < 0) { right = currentNode.Value; if (currentNode.Left == null) { return new Tuple<TValue, TValue>(left, right); } currentNode = currentNode.Left; } else { left = currentNode.Value; if (currentNode.Right == null) { return new Tuple<TValue, TValue>(left, right); } currentNode = currentNode.Right; } } }
/// <summary> /// Tries to move to a node based on its index /// </summary> /// <param name="index">Index</param> /// <returns>Node</returns> /// <exception cref="IndexOutOfRangeException">Thrown if the index is out of range</exception> protected IBinaryTreeNode <TKey, TValue> MoveToIndex(int index) { if (this.Root == null) { throw new IndexOutOfRangeException(); } int count = this.Root.Size; if (index < 0 || index >= count) { throw new IndexOutOfRangeException(); } // Special cases // Index 0 and only one node, return the root if (index == 0 && count == 1) { return(this.Root); } // Index 0, return the left most child if (index == 0) { return(this.Root.FindLeftmostChild()); } // Index == count - 1, return the right most child if (index == count - 1) { return(this.Root.FindRightmostChild()); } long baseIndex = 0; IBinaryTreeNode <TKey, TValue> currentNode = this.Root; while (true) { long currentIndex = currentNode.LeftChild != null ? baseIndex + currentNode.LeftChild.Size : baseIndex; if (currentIndex == index) { return(currentNode); } if (currentIndex > index) { // We're at a node where our calculated index is greater than the desired so need to move to the left sub-tree currentNode = currentNode.LeftChild; continue; } // We're at a node where our calculated index is less than the desired so need to move to the right sub-tree // Plus we need to adjust the base appropriately if (currentNode.RightChild != null) { currentNode = currentNode.RightChild; baseIndex = currentIndex + 1; continue; } throw new InvalidOperationException(); } }
public IBinaryTreeNode <TResult> Visit(BinaryTreeNode <TItem> node) { TResult mappedItem = selector(node.Item); IBinaryTreeNode <TResult> mappedLeft = node.Left.Accept(this); IBinaryTreeNode <TResult> mappedRight = node.Right.Accept(this); return(BinaryTree.Node(mappedItem, mappedLeft, mappedRight)); }
/// <summary> /// Creates a new instance of a tree node. /// </summary> /// <param name="parent">The parent of the node to create.</param> public BinaryTreeNode(IBinaryTreeNode parent) : this(parent, null) { }
/// <summary> /// Clears the binary tree of all of its items. /// </summary> public virtual void Clear() { _root = null; }
/// <summary> /// Default constructor. /// </summary> public BinaryTree() { _root = null; }
private static int NodeHeight(IBinaryTreeNode<int, int> tree) { if (tree == null) return 0; return Math.Max(NodeHeight(tree.Left), NodeHeight(tree.Right)) + 1; }
protected virtual string PreorderTraversal(IBinaryTreeNode current, string separator) { if (current != null) { StringBuilder sb = new StringBuilder(); sb.Append(current.Value.ToString()); sb.Append(separator); sb.Append(PreorderTraversal(current.LeftChild, separator)); sb.Append(PreorderTraversal(current.RightChild, separator)); return sb.ToString(); } else return String.Empty; }
/// <summary> /// Creates a new instance of a tree node. /// </summary> /// <param name="parent">The parent of the node to create.</param> /// <param name="Value">The value stored at the tree node.</param> public BinaryTreeNode(IBinaryTreeNode parent, object Value) : base(parent, Value, new TreeNodes(2)) { }
/// <summary> /// Builds an arraylist of the inorder traversal of the tree. /// </summary> /// <param name="current">The current binary tree node.</param> /// <param name="contents">The contents of the tree.</param> protected virtual void InorderTraversalBuildup(IBinaryTreeNode current, System.Collections.ArrayList contents) { if (current != null) { InorderTraversalBuildup(current.LeftChild, contents); contents.Add(current); InorderTraversalBuildup(current.RightChild, contents); } }
/// <summary> /// Search helper method that assists in locating the current binary node for the specified data item. /// </summary> /// <param name="current">The current node to begin the search with.</param> /// <param name="data">The data to look for.</param> /// <returns>A reference to the node that the data is contained in.</returns> protected virtual IBinaryTreeNode SearchHelper(IBinaryTreeNode current, IComparable data) { if (current == null) return null; // node was not found else { // get the comparable instance from the value of the object. IComparable currval = current.Value as IComparable; // if the current value is not comparable return null stating that we can not locate the node. if (currval == null) return null; // get the compare to results int result = currval.CompareTo(data); if (result == 0) // they are equal - we found the data return current; else if (result > 0) { // current.Value > n.Value // therefore, if the data exists it is in current's left subtree return SearchHelper(current.LeftChild, data); } else // result < 0 { // current.Value < n.Value // therefore, if the data exists it is in current's right subtree return SearchHelper(current.RightChild, data); } } }