/// <summary> /// Try to remove the key, and return the resulting Dict /// if the key is not found, old_node is Empty, else old_node is the Dict /// with matching Key /// </summary> public AvlNode <T> RemoveFromNew(T val, Comparison <T> comparer, out AvlNode <T> old_node) { if (IsEmpty) { old_node = Empty; return(Empty); } int comp = comparer(Value, val); if (comp < 0) { var newgt = right.RemoveFromNew(val, comparer, out old_node); if (old_node.IsEmpty) { //Not found, so nothing changed return(this); } var newroot = new AvlNode <T> (Value, left, newgt); return(newroot.FixRootBalance()); } if (comp > 0) { var newlt = left.RemoveFromNew(val, comparer, out old_node); if (old_node.IsEmpty) { //Not found, so nothing changed return(this); } var newroot = new AvlNode <T> (Value, newlt, right); return(newroot.FixRootBalance()); } //found it old_node = this; return(RemoveRoot()); }
/// <summary> /// Return a new dict with the root key-value pair removed /// </summary> AvlNode <T> RemoveRoot() { if (IsEmpty) { return(this); } if (left.IsEmpty) { return(right); } if (right.IsEmpty) { return(left); } //Neither are empty: if (left._count < right._count) { //LTDict has fewer, so promote from GTDict to minimize depth AvlNode <T> min; var newgt = right.RemoveMin(out min); var newroot = new AvlNode <T> (min.Value, left, newgt); return(newroot.FixRootBalance()); } else { AvlNode <T> max; var newlt = left.RemoveMax(out max); var newroot = new AvlNode <T> (max.Value, newlt, right); return(newroot.FixRootBalance()); } }
/// <summary> /// Return a new tree with the key-value pair inserted /// If the key is already present, it replaces the value /// This operation is O(Log N) where N is the number of keys /// </summary> public AvlNode <T> InsertIntoNew(T val, Comparison <T> comparer) { if (IsEmpty) { return(new AvlNode <T> (val)); } AvlNode <T> newlt = left; AvlNode <T> newgt = right; int comp = comparer(Value, val); T newv = Value; if (comp < 0) { //Let the GTDict put it in: newgt = right.InsertIntoNew(val, comparer); } else if (comp > 0) { //Let the LTDict put it in: newlt = left.InsertIntoNew(val, comparer); } else { //Replace the current value: newv = val; } var newroot = new AvlNode <T> (newv, newlt, newgt); return(newroot.FixRootBalance()); }
AvlNode <T> RemoveMin(out AvlNode <T> min) { if (IsEmpty) { min = Empty; return(Empty); } if (left.IsEmpty) { //We are the minimum: min = this; return(right); } //Go down: var newlt = left.RemoveMin(out min); var newroot = new AvlNode <T> (Value, newlt, right); return(newroot.FixRootBalance()); }
AvlNode <T> RemoveMax(out AvlNode <T> max) { if (IsEmpty) { max = Empty; return(Empty); } if (right.IsEmpty) { //We are the max: max = this; return(left); } else { //Go down: var newgt = right.RemoveMax(out max); var newroot = new AvlNode <T> (Value, left, newgt); return(newroot.FixRootBalance()); } }
/// <summary> /// Return a new tree with the key-value pair inserted /// If the key is already present, it replaces the value /// This operation is O(Log N) where N is the number of keys /// </summary> public AvlNode <T> InsertIntoNew(int index, T val) { if (IsEmpty) { return(new AvlNode <T> (val)); } AvlNode <T> newlt = left; AvlNode <T> newgt = right; if (index <= left._count) { newlt = left.InsertIntoNew(index, val); } else { newgt = right.InsertIntoNew(index - left._count - 1, val); } var newroot = new AvlNode <T> (Value, newlt, newgt); return(newroot.FixRootBalance()); }
/// <summary> /// Try to remove the key, and return the resulting Dict /// if the key is not found, old_node is Empty, else old_node is the Dict /// with matching Key /// </summary> public AvlNode <T> RemoveFromNew(int index, out AvlNode <T> old_node) { if (IsEmpty) { old_node = Empty; return(Empty); } if (index < left._count) { var newlt = left.RemoveFromNew(index, out old_node); if (old_node.IsEmpty) { //Not found, so nothing changed return(this); } var newroot = new AvlNode <T> (Value, newlt, right); return(newroot.FixRootBalance()); } if (index > left._count) { var newgt = right.RemoveFromNew(index - left._count - 1, out old_node); if (old_node.IsEmpty) { //Not found, so nothing changed return(this); } var newroot = new AvlNode <T> (Value, left, newgt); return(newroot.FixRootBalance()); } //found it old_node = this; return(RemoveRoot()); }