namespace System.Collections.Generic; /// /// Treap implementation. /// /// Provided type. [Serializable] public sealed class Treap : ICollection where T : IComparable { #region Fields [Serializable] private class Node { public TKey Key; public int Priority; public Node? Left, Right; public Node(TKey key, int priority) { this.Key = key; this.Priority = priority; this.Left = null; this.Right = null; } } private readonly Random randomGen; private Node root = default!; private int count; #endregion #region Properties /// /// Count of values in the treap. /// public int Count { get { return this.count; } } /// /// Not implemented. /// public bool IsReadOnly => false; #endregion #region Constructors /// /// Constructor for treap. /// public Treap() { this.randomGen = new Random(); } #endregion #region Public Methods /// /// Adds value to the treap. /// /// Value to be added. public void Add(T value) { this.root = this.InsertNode(this.root, value); this.count++; } /// /// Removes value from treap. /// /// Value to be removed. public bool Remove(T value) { this.root = this.RemoveNode(this.root, value); this.count--; return true; } /// /// Clears the treap. /// public void Clear() { this.Clear(this.root); this.root = default!; this.count = 0; } /// /// Determines whether the treap contains the specified value. /// /// Value to locate in the treap. /// public bool Contains(T value) { return this.Find(this.root, value) != null; } /// /// Returns the treap structure as an ordered array. /// /// Ordered array containing the values stored in the treap. public T[]? ToArray() { if (this.root != null) { var array = new T[this.count]; var index = 0; this.ToArray(this.root, ref array, ref index); return array; } else { return default!; } } /// /// Copy the treap into the provided array. /// /// Array to be populated with the values contained in the array. /// Starting index of the array. public void CopyTo(T[] array, int arrayIndex) { this.ToArray(this.root, ref array, ref arrayIndex); } /// /// Enumerator that iterates over the treap. Note that the values are not guaranteed to be sorted. /// /// Enumerator that iterates over the treap. public IEnumerator GetEnumerator() { return this.GetEnumerator(this.root); } #endregion #region Private Methods private Node InsertNode(Node node, T key) { if (node == null) { node = new Node(key, this.randomGen.Next(0, 100)); return node; } else if (key.CompareTo(node.Key) <= 0) { node.Left = this.InsertNode(node.Left!, key); if (node.Left!.Priority > node.Priority) { node = this.RotateRight(node); } } else { node.Right = this.InsertNode(node.Right!, key); if (node.Right!.Priority > node.Priority) { node = this.RotateLeft(node); } } return node; } private Node RemoveNode(Node node, T key) { if (node == null) { return node!; } if (key.CompareTo(node.Key) < 0) { node.Left = this.RemoveNode(node.Left!, key); } else if (key.CompareTo(node.Key) > 0) { node.Right = this.RemoveNode(node.Right!, key); } else if (node.Left == null) { node = node.Right!; } else if (node.Right == null) { node = node.Left; } else if (node.Left.Priority < node.Right.Priority) { node = this.RotateLeft(node); node.Left = this.RemoveNode(node.Left!, key); } else { node = this.RotateRight(node); node.Right = this.RemoveNode(node.Right!, key); } return node; } private Node RotateRight(Node node) { Node temp = node.Left!, temp2 = temp.Right!; temp.Right = node; node.Left = temp2; return temp; } private Node RotateLeft(Node node) { Node temp = node.Right!, temp2 = temp.Left!; temp.Left = node; node.Right = temp2; return temp; } private void Clear(Node node) { if (node.Left != null) { this.Clear(node.Left); } if (node.Right != null) { this.Clear(node.Right); } node.Left = node.Right = null; } private Node Find(Node node, T key) { if (node == null) { return node!; } else { if (node.Key.CompareTo(key) < 0) { var found = this.Find(node.Left!, key); if (found == null) { found = this.Find(node.Right!, key); } return found; } else if (node.Key.CompareTo(key) > 0) { var found = this.Find(node.Right!, key); if (found == null) { found = this.Find(node.Left!, key); } return found; } else { return node; } } } private void ToArray(Node node, ref T[] array, ref int index) { if (node != null) { this.ToArray(node.Left!, ref array, ref index); array[index] = node.Key; index++; this.ToArray(node.Right!, ref array, ref index); } } private IEnumerator GetEnumerator(Node currentNode) { var queue = new Queue>(); queue.Enqueue(currentNode); while (queue.Count > 0) { currentNode = queue.Dequeue(); yield return currentNode.Key; if (currentNode.Left != null) { queue.Enqueue(currentNode.Left); } if (currentNode.Right != null) { queue.Enqueue(currentNode.Right); } } } IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } #endregion }