/// <summary> /// Fix the root balance if LTDict and GTDict have good balance /// Used to keep the depth less than 1.44 log_2 N (AVL tree) /// </summary> AvlNode <T> FixRootBalance() { int bal = Balance; if (Math.Abs(bal) < 2) { return(this); } if (bal == 2) { if (left.Balance == 1 || left.Balance == 0) { //Easy case: return(this.RotateToGT()); } if (left.Balance == -1) { //Rotate LTDict: var newlt = left.RotateToLT(); var newroot = new AvlNode <T> (Value, newlt, right); return(newroot.RotateToGT()); } throw new Exception(String.Format("LTDict too unbalanced: {0}", left.Balance)); } if (bal == -2) { if (right.Balance == -1 || right.Balance == 0) { //Easy case: return(this.RotateToLT()); } if (right.Balance == 1) { //Rotate GTDict: var newgt = right.RotateToGT(); var newroot = new AvlNode <T> (Value, left, newgt); return(newroot.RotateToLT()); } throw new Exception(String.Format("LTDict too unbalanced: {0}", left.Balance)); } //In this case we can show: |bal| > 2 //if( Math.Abs(bal) > 2 ) { throw new Exception(String.Format("Tree too out of balance: {0}", Balance)); }
public AvlNode <T> SetItem(int index, T val) { AvlNode <T> newlt = left; AvlNode <T> newgt = right; if (index < left._count) { newlt = left.SetItem(index, val); } else if (index > left._count) { newgt = right.SetItem(index - left._count - 1, val); } else { return(new AvlNode <T> (val, newlt, newgt)); } return(new AvlNode <T> (Value, newlt, newgt)); }
public AvlNode <T> SetItem(int index, T val) { AvlNode <T> newlt = left; AvlNode <T> newgt = right; if (index < left._count) { newlt = ToMutableIfNecessary(left).SetItem(index, val); } else if (index > left._count) { newgt = ToMutableIfNecessary(right).SetItem(index - left._count - 1, val); } else { return(NewOrMutate(val, newlt, newgt)); } return(NewOrMutate(Value, newlt, newgt)); }
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 = ToMutableIfNecessary(left).RemoveMin(out min); var newroot = NewOrMutate(Value, newlt, right); 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()); } }
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 = ToMutableIfNecessary(right).RemoveMax(out max); var newroot = NewOrMutate(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> /// 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 = ToMutableIfNecessary(left).InsertIntoNew(index, val); } else { newgt = ToMutableIfNecessary(right).InsertIntoNew(index - left._count - 1, val); } var newroot = NewOrMutate(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()); }
internal Builder(AvlNode <T> immutableRoot, IEqualityComparer <T> comparer) { root = immutableRoot.ToMutable(); valueComparer = comparer; }
internal ImmutableDictionary(AvlNode <KeyValuePair <TKey, TValue> > root, IEqualityComparer <TKey> keyComparer, IEqualityComparer <TValue> valueComparer) { this.root = root; this.keyComparer = keyComparer; this.valueComparer = valueComparer; }
internal ImmutableList(AvlNode <T> root, IEqualityComparer <T> equalityComparer) { this.root = root; this.valueComparer = equalityComparer; }
public MutableAvlNode(T val, AvlNode <T> lt, AvlNode <T> gt) : base(val, lt, gt) { }
public override AvlNode <T> ToMutableIfNecessary(AvlNode <T> node) { return(node.ToMutable()); }
public virtual AvlNode <T> NewOrMutate(T newValue, AvlNode <T> newLeft, AvlNode <T> newRight) { return(new AvlNode <T>(newValue, newLeft, newRight)); }
public virtual AvlNode <T> ToMutableIfNecessary(AvlNode <T> node) { return(node); }
public override AvlNode <T> NewOrMutate(T newValue, AvlNode <T> newLeft, AvlNode <T> newRight) { throw new NotSupportedException(); }
internal Builder(AvlNode <KeyValuePair <TKey, TValue> > root, IEqualityComparer <TKey> keyComparer, IEqualityComparer <TValue> valueComparer) { this.root = root.ToMutable(); this.keyComparer = keyComparer; this.valueComparer = valueComparer; }
public void Add(KeyValuePair <TKey, TValue> item) { root = root.InsertIntoNew(item, CompareKV); }
public void Clear() { root = new AvlNode <KeyValuePair <TKey, TValue> >().ToMutable(); }
public AvlNode() { right = Empty; left = Empty; }