using System; using System.Collections.Generic; using System.Linq; using System.Diagnostics; namespace ConsoleApplication1 { public sealed class Treap { private readonly Func Comparer; private readonly Treap Left; private readonly T Value; private readonly Treap Right; // book keeping private readonly Random Rnd; private readonly int Height; // not needed, only used to ensure that our tree is mostly balanced private readonly int Priority; public readonly int Count; public Treap(Func comparer) { this.Comparer = comparer; this.Priority = Int32.MinValue; this.Rnd = new Random(); } private Treap(Func comparer, Treap left, T value, Treap right, int priority) { this.Comparer = comparer; this.Left = left; this.Right = right; this.Value = value; this.Height = Math.Max(left.Height, right.Height) + 1; this.Count = left.Count + right.Count + 1; this.Rnd = left.Rnd; this.Priority = priority; } private Treap Make(Treap left, T value, Treap right, int priority) { return new Treap(Comparer, left, value, right, priority); } private Treap Make(Treap left, T value, Treap right) { return Make(left, value, right, Rnd.Next(Int32.MinValue, Int32.MaxValue)); } private bool IsEmpty { get { return Count == 0; } } public Treap Insert(T v) { if (IsEmpty) { return Make(this, v, this); } else { int compare = Comparer(v, Value); if (compare < 0) { return Make(Left.Insert(v), Value, Right, Priority).HeapifyLeft(); } else if (compare > 0) { return Make(Left, Value, Right.Insert(v), Priority).HeapifyRight(); } else { return this; } } } public Treap HeapifyLeft() { if (this.Priority < Left.Priority) { return RotateRight(); } return this; } public Treap HeapifyRight() { if (this.Priority < Right.Priority) { return RotateLeft(); } return this; } /// /// Left tree rotation. /// /// /// q Right Rotation p /// / \ --------------+ / \ /// p c a q /// / \ Left Rotation / \ /// a b +------------- b c /// private Treap RotateLeft() { if (this.IsEmpty || this.Right.IsEmpty) { return this; } T p = this.Value; int pPriority = this.Priority; T q = this.Right.Value; int qPriority = this.Right.Priority; Treap a = this.Left; Treap b = this.Right.Left; Treap c = this.Right.Right; return Make(Make(a, p, b, pPriority), q, c, qPriority); } /// /// Right tree rotation /// /// /// q Right Rotation p /// / \ --------------+ / \ /// p c a q /// / \ Left Rotation / \ /// a b +------------- b c /// private Treap RotateRight() { if (this.IsEmpty || this.Left.IsEmpty) { return this; } T q = this.Value; int qPriority = this.Priority; T p = this.Left.Value; int pPriority = this.Left.Priority; Treap a = this.Left.Left; Treap b = this.Left.Right; Treap c = this.Right; return Make(a, p, Make(b, q, c, qPriority), pPriority); } } }