/// <summary> /// Rearranges the array so that a[k]} contains the kth smallest key; /// a[0] through a[k-1] are less than (or equal to) a[k]; /// a[k+1] through a[n-1] are greater than (or equal to) a[k]. /// </summary> /// <param name="a">the array</param> /// <param name="k">the rank of the key</param> /// <returns>the key of rank k}</returns> public static T Select(T[] a, int k) { if (k < 0 || k >= a.Length) { throw new ArgumentOutOfRangeException(nameof(k), k, "out of bounds"); } StdRandom.shuffle(a); int lo = 0, hi = a.Length - 1; while (hi > lo) { int i = partition(a, lo, hi); if (i > k) { hi = i - 1; } else if (i < k) { lo = i + 1; } else { return(a[i]); } } return(a[lo]); }
/// <summary> /// Randomized insertion. /// make new node the root with uniform probability /// </summary> /// <param name="x"></param> /// <param name="key"></param> /// <param name="val"></param> /// <returns></returns> internal override BaseNode <TKey, TValue> PutKey(BaseNode <TKey, TValue> x, TKey key, TValue val) { if (x == null) { return(new BaseNode <TKey, TValue>(key, val, 1)); } int cmp = key.CompareTo(x.key); if (cmp == 0) { x.val = val; return(x); } if (StdRandom.bernoulli(1.0 / (x.Size + 1.0))) { return(PutRoot(x, key, val)); } if (cmp < 0) { x.left = PutKey(x.left, key, val); } else { x.right = PutKey(x.right, key, val); } x.UpdateSize(); return(x); }
/// <summary> /// Rearranges the array in ascending order, using the natural order. /// </summary> /// <param name="a">the array to be sorted</param> public static void Sort(T[] a) { StdRandom.shuffle(a); sort(a, 0, a.Length - 1); Debug.Assert(SortingHelper <T> .isSorted(a)); }
/// <summary> /// Randomized deletion. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private BaseNode <TKey, TValue> joinLR(BaseNode <TKey, TValue> a, BaseNode <TKey, TValue> b) { if (a == null) { return(b); } if (b == null) { return(a); } if (StdRandom.bernoulli((double)a.Size / (a.Size + b.Size))) { a.right = joinLR(a.right, b); a.UpdateSize(); return(a); } else { b.left = joinLR(a, b.left); b.UpdateSize(); return(b); } }