protected void InOrderTraverse2(BinaryTreeNode node, Action<BinaryTreeNode> fn = null) { if (node == null || node == predesessor) return; InOrderTraverse2(node.Left, fn); if (fn != null) fn(node); InOrderTraverse2(node.Right, fn); }
public BinaryTree MakeInOrderRightThreaded() { Head = new BinaryTreeNode(); Head.Left = root; Head.Right = Head; InOrderTraverse2(Head, (n) => { if (predesessor != null) { if (predesessor.Right == null) { predesessor.rightThread = false; predesessor.Right = n; } else { predesessor.rightThread = true; } } predesessor = n; }); return this; }
private int GetCount(BinaryTreeNode node) { if (node == null) return 0; int lcount = GetCount(node.Left); int rcount = node.rightThread ? GetCount(node.Right) : 0; return lcount + rcount + 1; }
private int GetHeight(BinaryTreeNode node) { if (node == null) return -1; int lheight = GetHeight(node.Left); int rheight = node.rightThread ? GetHeight(node.Right) : -1; return Math.Max(lheight, rheight) + 1; }
/// /// Adds a node to the tree /// public void Add(BinaryTreeNode node) //Do I need to invoke the balance method for this? { if (this.head == null) //'this' is the tree, check if empty { this.head = node; //set node as root of the tree //node.Parent = this.head; //its parent points to itself size++; } else { if (node.Parent == null) node.Parent = head; //start at head //Node is inserted on the left side if it is smaller or equal to the parent bool insertLeftSide = false; if (node.Value < node.Parent.Value) { insertLeftSide = true; } if (insertLeftSide) //insert on the left { if (node.Parent.LeftChild == null) { node.Parent.LeftChild = node; //insert in left size++; } else { node.Parent = node.Parent.LeftChild; //scan down to left child this.Add(node); //recursive call } } else //insert on the right { if (node.Parent.RightChild == null) { node.Parent.RightChild = node; //insert in right size++; } else { node.Parent = node.Parent.RightChild; this.Add(node); } } } }
// depth from node from the right public int heightR(BinaryTreeNode node) { if (node == null) return 0; return node.RightChild.level + 1; }
/// /// Create a new instance of a Binary Tree node /// public BinaryTreeNode(Int32 value) { this.level = 1; this.value = value; this.parent = null; this.leftChild = null; this.rightChild = null; }
/// /// Adds a new element to the tree /// public void Add(Int32 value) { BinaryTreeNode node = new BinaryTreeNode(value); this.Add(node); }
private void PostOrder(ref BinaryTreeNode node) { if (node == null) return; if (node.LeftChild != null) { InOrder(ref node.leftChild); } if (node.RightChild != null) { InOrder(ref node.rightChild); } Console.WriteLine(node.value); }
/// /// Creates a new instance of an empty node /// public BinaryTreeNode() { this.level = 0; this.parent = null; this.leftChild = null; this.rightChild = null; //deleted = null; }
private void InOrder(ref BinaryTreeNode node) { balance(node); //Where I was attempting to balance before traversing which I think is what throws the error. if (node == null) return; if (node.LeftChild != null) { InOrder(ref node.leftChild); } Console.WriteLine(node.value); if (node.RightChild != null) { InOrder(ref node.rightChild); } }
//private int depth; /// /// Constructor ‐ Creates a new instance of a Binary Tree /// public BinarySearchTree() { head = null; size = 0; }
// right rotation around node public BinaryTreeNode rotateR(BinaryTreeNode node) { if (node == null) return null; else { BinaryTreeNode newRoot = node.LeftChild; node.LeftChild = newRoot.RightChild; newRoot.RightChild = node; return newRoot; } }
private void DrawTree(BinaryTreeNode node, Graphics g) { int width = panel1.Width; int height = panel1.Height; int dx = 0, dy = 0, dx2 = 0, dy2 = 0, ys = 20, dc = 10; int x_scale = (int)(width / (tree.Root.Count + 1)); int y_scale = (int)((height - ys) / (tree.Root.Height + 1)); if (node != null) { int treeHeight = node.Height; DrawTree(node.Left, g); dx = node.Xpos * x_scale - ys; dy = node.Ypos * y_scale + ys; g.DrawString(node.ToString(), panel1.Font, blackBrush, new PointF(dx - ys, dy - dc)); if (!node.rightThread) { g.DrawString(string.Format("({0})", node.Right.ToString()), panel1.Font, redBrush, new PointF(dx + ys / 2, dy - dc)); } g.FillEllipse(blackBrush, dx - dc / 2, dy - dc / 2, dc, dc); if (node.Left != null) { dx2 = node.Left.Xpos * x_scale - ys; dy2 = node.Left.Ypos * y_scale + ys; g.DrawLine(blackPen, dx, dy, dx2, dy2); } if (node.Right != null && node.rightThread) { dx2 = node.Right.Xpos * x_scale - ys; dy2 = node.Right.Ypos * y_scale + ys; g.DrawLine(blackPen, dx, dy, dx2, dy2); } if (node.rightThread) { DrawTree(node.Right, g); } } }
//----------------------------------- // balancing the binary tree // after the tree has been built // // WARNING! This code has not been checked... // and you may need to change it // depending on your tree design //------------------------------------ public void balance(BinaryTreeNode node) { if (node == null) { } if (node != null) { BinarySearchTree tree = new BinarySearchTree(); if (node.RightChild.level - node.LeftChild.level > 1) { if (node.RightChild.level > node.LeftChild.level) { node = rotateL(node); node = rotateR(node); } else { node = rotateL(node); } } else { if (node.LeftChild.level > node.RightChild.level) { node = rotateR(node); node = rotateL(node); } else { node = rotateR(node); } } balance(node.LeftChild); balance(node.RightChild); } }
/// /// Removes a node from the tree and returns whether the removal was successful. ///> /// public bool Remove(BinaryTreeNode removeNode) { if (removeNode == null) return false; //value doesn't exist or not of this tree //Note whether the node to be removed is the root of the tree bool wasHead = (removeNode == head); if (this.Count == 1) { this.head = null; //only element was the root size--; //decrease total element count } else if (removeNode.IsLeaf) //Case 1: No Children { //Remove node from its parent if (removeNode.IsLeftChild) { removeNode.Parent.LeftChild = null; } else { removeNode.Parent.RightChild = null; } removeNode.Parent = null; size--; //decrease total element count } else if (removeNode.ChildCount == 1) //Case 2: One Child { if (removeNode.HasLeftChild) { //Put left child node in place of the node to be removed removeNode.LeftChild.Parent = removeNode.Parent; //update parent if (wasHead) { this.Root = removeNode.LeftChild; //update root reference if needed } if (removeNode.IsLeftChild) //update the parent's child reference { removeNode.Parent.LeftChild = removeNode.LeftChild; } else { removeNode.Parent.RightChild = removeNode.LeftChild; } } else //Has right child { //Put left node in place of the node to be removed removeNode.RightChild.Parent = removeNode.Parent; //update parent if (wasHead) { this.Root = removeNode.RightChild; //update root reference if needed } if (removeNode.IsLeftChild) //update the parent's child reference { removeNode.Parent.LeftChild = removeNode.RightChild; } else { removeNode.Parent.RightChild = removeNode.RightChild; } } removeNode.Parent = null; removeNode.LeftChild = null; removeNode.RightChild = null; size--; //decrease total element count } else //Case 3: Two Children { //Find inorder predecessor (right‐most node in left subtree) BinaryTreeNode successorNode = removeNode.LeftChild; while (successorNode.RightChild != null) { successorNode = successorNode.RightChild; } removeNode.Value = successorNode.Value; //replace value this.Remove(successorNode); //recursively remove the inorder predecessor } return true; }
protected void InOrderTraverse(BinaryTreeNode node, Action<BinaryTreeNode, int> fn = null, int depth = 1) { if (node == null) return; InOrderTraverse(node.Left, fn, depth + 1); if (fn != null) fn(node, depth); InOrderTraverse(node.Right, fn, depth + 1); }