public bool Insert(T data) { /* if (!(data is ValueType) && EqualityComparer<T>.Default.Equals(data, default(T)) ) * { * return false; * } * else */if (m_Root == m_Bottom) { // create root node m_Root = CreateNode(data); return(true); } else { Node currentNode = m_Root; Node parent = null; int comparisonResult = 1; // initial value for loop condition to hold // store traversal history in stack Stack <TraversalHistory> nodeStack = new Stack <TraversalHistory>((int)Math.Ceiling(Math.Log(Count + 1, 2)) + 1); nodeStack.Push(new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.ISROOT)); while (currentNode != m_Bottom) { parent = currentNode; comparisonResult = CompareTo(data, currentNode.Data, COMPARISON_TYPE.INSERT); TraversalHistory histEntry; // switch between left or right if (comparisonResult <= 0) { currentNode = currentNode.Left; histEntry = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.LEFT); nodeStack.Push(histEntry); } else if (comparisonResult > 0) { currentNode = currentNode.Right; histEntry = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.RIGHT); nodeStack.Push(histEntry); } } // check if traversed until bottom bool didInsert = false; if (nodeStack.Pop().node == m_Bottom) // This node must be m_Bottom. { // use last comparison result and parent to insert new node if (comparisonResult <= 0) { parent.Left = CreateNode(data); didInsert = true; } else if (comparisonResult > 0) { parent.Right = CreateNode(data); didInsert = true; } } // pop history stack and change shift tree when necessary while (nodeStack.Count != 0) { TraversalHistory t = nodeStack.Pop(); Node n = t.node; n = Skew(n, t.parentNode, t.side); Split(n, t.parentNode, t.side); } // return whether a node was inserted return(didInsert); } }
public bool Delete(T data) { if (m_Root == m_Bottom /*|| EqualityComparer<T>.Default.Equals(data, default(T)) */) { return(false); } Node currentNode = m_Root; Node parent = null; Node deleted = m_Bottom; Stack <TraversalHistory> nodeStack = new Stack <TraversalHistory>((int)Math.Ceiling(Math.Log(Count + 1, 2)) + 1); nodeStack.Push(new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.ISROOT)); while (currentNode != m_Bottom) { parent = currentNode; TraversalHistory hist; int comparisonResult = CompareTo(data, currentNode.Data, COMPARISON_TYPE.DELETE); if (comparisonResult < 0) { currentNode = currentNode.Left; hist = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.LEFT); } else { deleted = currentNode; currentNode = currentNode.Right; hist = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.RIGHT); } nodeStack.Push(hist); } bool didDelete = false; if (deleted != m_Bottom && CompareTo(data, deleted.Data, COMPARISON_TYPE.DELETE) == 0) { if (nodeStack.Pop().node != m_Bottom) // Pop since the last entry is m_Bottom { throw new Exception("First node in traversal history was not Bottom!"); } TraversalHistory lastHist = nodeStack.Pop(); Node last = lastHist.node; // This is the node that is leftmost of the node that we want to delete. if (last.Left != m_Bottom) { throw new Exception("Last has a left child that is not Bottom!"); } deleted.Data = last.Data; Node copy = last.Right; if (copy != m_Bottom) { last.Data = copy.Data; last.Left = copy.Left; last.Right = copy.Right; last.Level = copy.Level; // Destroy the node copy.Left = null; copy.Right = null; copy.Data = default(T); } else { if (lastHist.side == TraversalHistory.ECHILDSIDE.LEFT) { lastHist.parentNode.Left = m_Bottom; } else if (lastHist.side == TraversalHistory.ECHILDSIDE.RIGHT) { lastHist.parentNode.Right = m_Bottom; } else { m_Root = m_Bottom; } } --Count; didDelete = true; } // pop history stack and change tree when necessary while (nodeStack.Count != 0) { TraversalHistory t = nodeStack.Pop(); Node n = t.node; if (n.Left.Level < n.Level - 1 || n.Right.Level < n.Level - 1) { --n.Level; if (n.Right.Level > n.Level) { n.Right.Level = n.Level; } n = Skew(n, t.parentNode, t.side); n.Right = Skew(n.Right, n, TraversalHistory.ECHILDSIDE.RIGHT); n.Right.Right = Skew(n.Right.Right, n.Right, TraversalHistory.ECHILDSIDE.RIGHT); n = Split(n, t.parentNode, t.side); n.Right = Split(n.Right, n, TraversalHistory.ECHILDSIDE.RIGHT); } } return(didDelete); }