Improve IHttpClient factories (#20)

Codestyle fixes
Setup CODEOWNERS
Setup dependabot
This commit is contained in:
2022-09-06 15:49:07 +02:00
committed by GitHub
parent 3c741ab969
commit e6a06915cd
99 changed files with 8108 additions and 7558 deletions
@@ -1,393 +1,402 @@
using System.Collections.Generic;
namespace System.Collections.Generic
{
/// <summary>
/// AVL tree implementation.
/// Thanks to Karim Oumghar for the implementation example.
/// Read on https://simpledevcode.wordpress.com/2014/09/16/avl-tree-in-c/
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class AVLTree<T> : ICollection<T> where T : IComparable<T>
{
#region Fields
[Serializable]
private class AVLNode<TKey>
{
public TKey Value;
public AVLNode<TKey> Left;
public AVLNode<TKey> Right;
public AVLNode(TKey value)
{
this.Value = value;
}
}
AVLNode<T> root;
private int count = 0;
private readonly bool isReadOnly = false;
#endregion
#region Properties
/// <summary>
/// Count of items currently stored in the tree.
/// </summary>
public int Count
{
get
{
return count;
}
}
/// <summary>
/// True if the collection is readonly. False otherwise.
/// </summary>
public bool IsReadOnly => isReadOnly;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of an AVLTree collection.
/// </summary>
public AVLTree()
{
namespace System.Collections.Generic;
}
#endregion
#region Public Methods
/// <summary>
/// Adds the value to the tree.
/// </summary>
/// <param name="value">Value to be added to the tree.</param>
public void Add(T value)
/// <summary>
/// AVL tree implementation.
/// Thanks to Karim Oumghar for the implementation example.
/// Read on https://simpledevcode.wordpress.com/2014/09/16/avl-tree-in-c/
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class AVLTree<T> : ICollection<T> where T : IComparable<T>
{
#region Fields
[Serializable]
private class AVLNode<TKey>
{
public TKey Value;
public AVLNode<TKey> Left;
public AVLNode<TKey> Right;
public AVLNode(TKey value)
{
count++;
var newItem = new AVLNode<T>(value);
if (root == null)
{
root = newItem;
}
else
{
root = RecursiveInsertion(root, newItem);
}
this.Value = value;
}
/// <summary>
/// Checks if the key is contained into the tree.
/// </summary>
/// <param name="value">Value to be checked if present in the tree.</param>
/// <returns>True if the value is in the tree.</returns>
public bool Contains(T value)
}
AVLNode<T> root;
private int count = 0;
private readonly bool isReadOnly = false;
#endregion
#region Properties
/// <summary>
/// Count of items currently stored in the tree.
/// </summary>
public int Count
{
get
{
var node = Find(value, root);
if (node == null)
{
return false;
}
if (node.Value.CompareTo(value) == 0)
{
return true;
}
else
{
return false;
}
return this.count;
}
/// <summary>
/// Removes the specified value from the tree.
/// </summary>
/// <param name="value">Value to be deleted.</param>
public bool Remove(T value)
}
/// <summary>
/// True if the collection is readonly. False otherwise.
/// </summary>
public bool IsReadOnly => this.isReadOnly;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of an AVLTree collection.
/// </summary>
public AVLTree()
{
}
#endregion
#region Public Methods
/// <summary>
/// Adds the value to the tree.
/// </summary>
/// <param name="value">Value to be added to the tree.</param>
public void Add(T value)
{
this.count++;
var newItem = new AVLNode<T>(value);
if (this.root == null)
{
this.root = newItem;
}
else
{
this.root = this.RecursiveInsertion(this.root, newItem);
}
}
/// <summary>
/// Checks if the key is contained into the tree.
/// </summary>
/// <param name="value">Value to be checked if present in the tree.</param>
/// <returns>True if the value is in the tree.</returns>
public bool Contains(T value)
{
var node = this.Find(value, this.root);
if (node == null)
{
return false;
}
if (node.Value.CompareTo(value) == 0)
{
root = Delete(root, value);
return true;
}
/// <summary>
/// Clears the tree.
/// </summary>
public void Clear()
else
{
var queue = new Queue<AVLNode<T>>();
queue.Enqueue(root);
return false;
}
}
/// <summary>
/// Removes the specified value from the tree.
/// </summary>
/// <param name="value">Value to be deleted.</param>
public bool Remove(T value)
{
this.root = this.Delete(this.root, value);
return true;
}
/// <summary>
/// Clears the tree.
/// </summary>
public void Clear()
{
var queue = new Queue<AVLNode<T>>();
queue.Enqueue(this.root);
while (queue.Count > 0)
{
var currentNode = queue.Dequeue();
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
currentNode.Left = null;
count--;
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
currentNode.Right = null;
count--;
}
}
root = null;
count--;
}
/// <summary>
/// Copies the tree onto the provided array.
/// </summary>
/// <param name="array">Array to store the values in the tree.</param>
/// <param name="arrayIndex">Starting index of the provided array.</param>
public void CopyTo(T[] array, int arrayIndex)
while (queue.Count > 0)
{
var queue = new Queue<AVLNode<T>>();
queue.Enqueue(root);
while (queue.Count > 0)
var currentNode = queue.Dequeue();
if (currentNode.Left != null)
{
var currentNode = queue.Dequeue();
array[arrayIndex++] = currentNode.Value;
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
}
queue.Enqueue(currentNode.Left);
currentNode.Left = null;
this.count--;
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
currentNode.Right = null;
this.count--;
}
}
/// <summary>
/// Enumerator that iterates over the tree.
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
this.root = null;
this.count--;
}
/// <summary>
/// Copies the tree onto the provided array.
/// </summary>
/// <param name="array">Array to store the values in the tree.</param>
/// <param name="arrayIndex">Starting index of the provided array.</param>
public void CopyTo(T[] array, int arrayIndex)
{
var queue = new Queue<AVLNode<T>>();
queue.Enqueue(this.root);
while (queue.Count > 0)
{
return GetEnumerator(root);
var currentNode = queue.Dequeue();
array[arrayIndex++] = currentNode.Value;
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
}
}
/// <summary>
/// Copies the tree structure into an array.
/// </summary>
/// <returns>Array containing the values contained in the tree.</returns>
public T[] ToArray()
}
/// <summary>
/// Enumerator that iterates over the tree.
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
return this.GetEnumerator(this.root);
}
/// <summary>
/// Copies the tree structure into an array.
/// </summary>
/// <returns>Array containing the values contained in the tree.</returns>
public T[] ToArray()
{
var array = new T[this.count];
this.CopyTo(array, 0);
return array;
}
#endregion
#region Private Methods
private AVLNode<T> RecursiveInsertion(AVLNode<T> current, AVLNode<T> n)
{
if (current == null)
{
var array = new T[count];
CopyTo(array, 0);
return array;
}
#endregion
#region Private Methods
private AVLNode<T> RecursiveInsertion(AVLNode<T> current, AVLNode<T> n)
{
if (current == null)
{
current = n;
return current;
}
else if (n.Value.CompareTo(current.Value) < 0)
{
current.Left = RecursiveInsertion(current.Left, n);
current = BalanceTree(current);
}
else if (n.Value.CompareTo(current.Value) > 0)
{
current.Right = RecursiveInsertion(current.Right, n);
current = BalanceTree(current);
}
current = n;
return current;
}
private AVLNode<T> BalanceTree(AVLNode<T> current)
else if (n.Value.CompareTo(current.Value) < 0)
{
var b_factor = BalanceFactor(current);
if (b_factor > 1)
{
if (BalanceFactor(current.Left) > 0)
{
current = RotateLL(current);
}
else
{
current = RotateLR(current);
}
}
else if (b_factor < -1)
{
if (BalanceFactor(current.Right) > 0)
{
current = RotateRL(current);
}
else
{
current = RotateRR(current);
}
}
return current;
current.Left = this.RecursiveInsertion(current.Left, n);
current = this.BalanceTree(current);
}
private AVLNode<T> Delete(AVLNode<T> current, T target)
else if (n.Value.CompareTo(current.Value) > 0)
{
AVLNode<T> parent;
if (current == null)
{ return null; }
current.Right = this.RecursiveInsertion(current.Right, n);
current = this.BalanceTree(current);
}
return current;
}
private AVLNode<T> BalanceTree(AVLNode<T> current)
{
var b_factor = this.BalanceFactor(current);
if (b_factor > 1)
{
if (this.BalanceFactor(current.Left) > 0)
{
current = this.RotateLL(current);
}
else
{
//left subtree
if (target.CompareTo(current.Value) < 0)
{
current.Left = Delete(current.Left, target);
if (BalanceFactor(current) == -2)//here
{
if (BalanceFactor(current.Right) <= 0)
{
current = RotateRR(current);
}
else
{
current = RotateRL(current);
}
}
}
//right subtree
else if (target.CompareTo(current.Value) > 0)
{
current.Right = Delete(current.Right, target);
if (BalanceFactor(current) == 2)
{
if (BalanceFactor(current.Left) >= 0)
{
current = RotateLL(current);
}
else
{
current = RotateLR(current);
}
}
}
//if target is found
else
{
count--;
if (current.Right != null)
{
//delete its inorder successor
parent = current.Right;
while (parent.Left != null)
{
parent = parent.Left;
}
current.Value = parent.Value;
current.Right = Delete(current.Right, parent.Value);
if (BalanceFactor(current) == 2)//rebalancing
{
if (BalanceFactor(current.Left) >= 0)
{
current = RotateLL(current);
}
else { current = RotateLR(current); }
}
}
else
{ //if current.left != null
return current.Left;
}
}
current = this.RotateLR(current);
}
return current;
}
private AVLNode<T> Find(T target, AVLNode<T> current)
else if (b_factor < -1)
{
if (current == null)
if (this.BalanceFactor(current.Right) > 0)
{
return null;
current = this.RotateRL(current);
}
else
{
current = this.RotateRR(current);
}
}
return current;
}
private AVLNode<T> Delete(AVLNode<T> current, T target)
{
AVLNode<T> parent;
if (current == null)
{ return null; }
else
{
//left subtree
if (target.CompareTo(current.Value) < 0)
{
if (target.CompareTo(current.Value) == 0)
current.Left = this.Delete(current.Left, target);
if (this.BalanceFactor(current) == -2)//here
{
return current;
if (this.BalanceFactor(current.Right) <= 0)
{
current = this.RotateRR(current);
}
else
{
current = this.RotateRL(current);
}
}
}
//right subtree
else if (target.CompareTo(current.Value) > 0)
{
current.Right = this.Delete(current.Right, target);
if (this.BalanceFactor(current) == 2)
{
if (this.BalanceFactor(current.Left) >= 0)
{
current = this.RotateLL(current);
}
else
{
current = this.RotateLR(current);
}
}
}
//if target is found
else
{
this.count--;
if (current.Right != null)
{
//delete its inorder successor
parent = current.Right;
while (parent.Left != null)
{
parent = parent.Left;
}
current.Value = parent.Value;
current.Right = this.Delete(current.Right, parent.Value);
if (this.BalanceFactor(current) == 2)//rebalancing
{
if (this.BalanceFactor(current.Left) >= 0)
{
current = this.RotateLL(current);
}
else { current = this.RotateLR(current); }
}
}
else
{
return Find(target, current.Left);
{ //if current.left != null
return current.Left;
}
}
}
return current;
}
private AVLNode<T> Find(T target, AVLNode<T> current)
{
if (current == null)
{
return null;
}
if (target.CompareTo(current.Value) < 0)
{
if (target.CompareTo(current.Value) == 0)
{
return current;
}
else
{
if (target.CompareTo(current.Value) == 0)
{
return current;
}
else
{
return Find(target, current.Right);
}
return this.Find(target, current.Left);
}
}
private int Max(int l, int r)
else
{
return l > r ? l : r;
}
private int GetHeight(AVLNode<T> current)
{
var height = 0;
if (current != null)
if (target.CompareTo(current.Value) == 0)
{
var l = GetHeight(current.Left);
var r = GetHeight(current.Right);
var m = Max(l, r);
height = m + 1;
return current;
}
return height;
}
private int BalanceFactor(AVLNode<T> current)
{
var l = GetHeight(current.Left);
var r = GetHeight(current.Right);
var b_factor = l - r;
return b_factor;
}
private AVLNode<T> RotateRR(AVLNode<T> parent)
{
var pivot = parent.Right;
parent.Right = pivot.Left;
pivot.Left = parent;
return pivot;
}
private AVLNode<T> RotateLL(AVLNode<T> parent)
{
var pivot = parent.Left;
parent.Left = pivot.Right;
pivot.Right = parent;
return pivot;
}
private AVLNode<T> RotateLR(AVLNode<T> parent)
{
var pivot = parent.Left;
parent.Left = RotateRR(pivot);
return RotateLL(parent);
}
private AVLNode<T> RotateRL(AVLNode<T> parent)
{
var pivot = parent.Right;
parent.Right = RotateLL(pivot);
return RotateRR(parent);
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
private IEnumerator<T> GetEnumerator(AVLNode<T> rootNode)
{
var queue = new Queue<AVLNode<T>>();
queue.Enqueue(rootNode);
while (queue.Count > 0)
else
{
var currentNode = queue.Dequeue();
yield return currentNode.Value;
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
}
return this.Find(target, current.Right);
}
}
#endregion
}
private int Max(int l, int r)
{
return l > r ? l : r;
}
private int GetHeight(AVLNode<T> current)
{
var height = 0;
if (current != null)
{
var l = this.GetHeight(current.Left);
var r = this.GetHeight(current.Right);
var m = this.Max(l, r);
height = m + 1;
}
return height;
}
private int BalanceFactor(AVLNode<T> current)
{
var l = this.GetHeight(current.Left);
var r = this.GetHeight(current.Right);
var b_factor = l - r;
return b_factor;
}
private AVLNode<T> RotateRR(AVLNode<T> parent)
{
var pivot = parent.Right;
parent.Right = pivot.Left;
pivot.Left = parent;
return pivot;
}
private AVLNode<T> RotateLL(AVLNode<T> parent)
{
var pivot = parent.Left;
parent.Left = pivot.Right;
pivot.Right = parent;
return pivot;
}
private AVLNode<T> RotateLR(AVLNode<T> parent)
{
var pivot = parent.Left;
parent.Left = this.RotateRR(pivot);
return this.RotateLL(parent);
}
private AVLNode<T> RotateRL(AVLNode<T> parent)
{
var pivot = parent.Right;
parent.Right = this.RotateLL(pivot);
return this.RotateRR(parent);
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
private IEnumerator<T> GetEnumerator(AVLNode<T> rootNode)
{
var queue = new Queue<AVLNode<T>>();
queue.Enqueue(rootNode);
while (queue.Count > 0)
{
var currentNode = queue.Dequeue();
yield return currentNode.Value;
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
}
}
}
#endregion
}
@@ -1,214 +1,219 @@
using System.Linq;
namespace System.Collections.Generic
namespace System.Collections.Generic;
/// <summary>
/// Binary heap implementation.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class BinaryHeap<T> : IEnumerable<T> where T : IComparable<T>
{
#region Fields
T[] items;
private int capacity;
private int count;
private readonly int initialCapacity;
#endregion
#region Properties
/// <summary>
/// Binary heap implementation.
/// Minimum value from the heap.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class BinaryHeap<T> : IEnumerable<T> where T : IComparable<T>
public T Min
{
#region Fields
T[] items;
private int capacity;
private int count;
private readonly int initialCapacity;
#endregion
#region Properties
/// <summary>
/// Minimum value from the heap.
/// </summary>
public T Min
get
{
get
{
return items[1];
}
return this.items[1];
}
/// <summary>
/// Maximum value from the heap.
/// </summary>
public T Max
{
get
{
return items[count];
}
}
/// <summary>
/// Capacity of the heap.
/// </summary>
public int Capacity
{
get => capacity;
set
{
if (value > capacity)
{
Array.Resize(ref items, value);
capacity = value;
}
}
}
/// <summary>
/// Number of elements in the heap.
/// </summary>
public int Count { get => count; }
#endregion
#region Constructors
/// <summary>
/// Constructor for a binary heap data structure.
/// </summary>
public BinaryHeap()
{
capacity = 10;
initialCapacity = capacity;
items = new T[capacity];
}
/// <summary>
/// Constructor for a binary heap data structure.
/// </summary>
/// <param name="capacity">Initial capacity of the heap. Used for initial alocation of the array.</param>
public BinaryHeap(int capacity)
{
this.capacity = capacity;
initialCapacity = capacity;
items = new T[capacity];
}
#endregion
#region Public Methods
/// <summary>
/// Adds value to the queue.
/// </summary>
/// <param name="value">Value to be added.</param>
public void Add(T value)
{
if (count == Capacity - 1)
{
Capacity = 2 * Capacity;
}
var position = ++count;
for (; position > 1 && value.CompareTo(items[position / 2]) < 0; position /= 2)
{
items[position] = items[position / 2];
}
items[position] = value;
}
/// <summary>
/// Removes the item at the root. Throws exception if there are no items in the heap.
/// </summary>
/// <returns>Value removed.</returns>
public T Remove()
{
if (count == 0)
{
throw new IndexOutOfRangeException("Heap is empty!");
}
var min = items[1];
items[1] = items[count--];
BubbleDown(1);
return min;
}
/// <summary>
/// Peeks at the item at the root. Throws exception if there are no items in the heap.
/// </summary>
/// <returns></returns>
public T Peek()
{
if (count == 0)
{
throw new IndexOutOfRangeException("Heap is empty!");
}
var min = items[1];
return min;
}
/// <summary>
/// Return the heap structure as an array
/// </summary>
/// <returns>Array with values sorted as in heap</returns>
public T[] ToArray()
{
var newArray = new T[count];
Array.Copy(items, 1, newArray, 0, count);
return newArray;
}
/// <summary>
/// Determines whether the heap contains specified value
/// </summary>
/// <param name="value">Value to locate in the heap</param>
/// <returns></returns>
public bool Contains(T value)
{
return items.Contains(value);
}
/// <summary>
/// Clears the heap
/// </summary>
public void Clear()
{
count = 0;
}
/// <summary>
/// Clears the heap.
/// </summary>
/// <param name="completeClear">Specifies if the underlying array should be cleared as well</param>
public void Clear(bool completeClear)
{
count = 0;
if (completeClear)
{
capacity = initialCapacity;
items = new T[initialCapacity];
}
}
/// <summary>
/// Returns an enumerator that iterates over the heap.
/// </summary>
/// <returns>Enumerator that iterates over the heap.</returns>
public IEnumerator<T> GetEnumerator()
{
for (var i = 0; i < count; i++)
{
yield return items[i + 1];
}
}
#endregion
#region Private Methods
/// <summary>
/// Bubble the specified element to its position
/// </summary>
/// <param name="index">Index of element to bubble</param>
private void BubbleDown(int index)
{
var temp = items[index];
int childIndex;
for (; 2 * index <= count; index = childIndex)
{
childIndex = 2 * index;
if (childIndex != Count && items[childIndex].CompareTo(items[childIndex + 1]) > 0)
{
childIndex++;
}
if (temp.CompareTo(items[childIndex]) > 0)
{
items[index] = items[childIndex];
}
else
{
break;
}
}
items[index] = temp;
}
/// <summary>
/// Implementation of IEnumerator.
/// </summary>
/// <returns>Enumerator over the array.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
/// <summary>
/// Maximum value from the heap.
/// </summary>
public T Max
{
get
{
return this.items[this.count];
}
}
/// <summary>
/// Capacity of the heap.
/// </summary>
public int Capacity
{
get => this.capacity;
set
{
if (value > this.capacity)
{
Array.Resize(ref this.items, value);
this.capacity = value;
}
}
}
/// <summary>
/// Number of elements in the heap.
/// </summary>
public int Count { get => this.count; }
#endregion
#region Constructors
/// <summary>
/// Constructor for a binary heap data structure.
/// </summary>
public BinaryHeap()
{
this.capacity = 10;
this.initialCapacity = this.capacity;
this.items = new T[this.capacity];
}
/// <summary>
/// Constructor for a binary heap data structure.
/// </summary>
/// <param name="capacity">Initial capacity of the heap. Used for initial alocation of the array.</param>
public BinaryHeap(int capacity)
{
this.capacity = capacity;
this.initialCapacity = capacity;
this.items = new T[capacity];
}
#endregion
#region Public Methods
/// <summary>
/// Adds value to the queue.
/// </summary>
/// <param name="value">Value to be added.</param>
public void Add(T value)
{
if (this.count == this.Capacity - 1)
{
this.Capacity = 2 * this.Capacity;
}
var position = ++this.count;
for (; position > 1 && value.CompareTo(this.items[position / 2]) < 0; position /= 2)
{
this.items[position] = this.items[position / 2];
}
this.items[position] = value;
}
/// <summary>
/// Removes the item at the root. Throws exception if there are no items in the heap.
/// </summary>
/// <returns>Value removed.</returns>
public T Remove()
{
if (this.count == 0)
{
throw new IndexOutOfRangeException("Heap is empty!");
}
var min = this.items[1];
this.items[1] = this.items[this.count--];
this.BubbleDown(1);
return min;
}
/// <summary>
/// Peeks at the item at the root. Throws exception if there are no items in the heap.
/// </summary>
/// <returns></returns>
public T Peek()
{
if (this.count == 0)
{
throw new IndexOutOfRangeException("Heap is empty!");
}
var min = this.items[1];
return min;
}
/// <summary>
/// Return the heap structure as an array
/// </summary>
/// <returns>Array with values sorted as in heap</returns>
public T[] ToArray()
{
var newArray = new T[this.count];
Array.Copy(this.items, 1, newArray, 0, this.count);
return newArray;
}
/// <summary>
/// Determines whether the heap contains specified value
/// </summary>
/// <param name="value">Value to locate in the heap</param>
/// <returns></returns>
public bool Contains(T value)
{
return this.items.Contains(value);
}
/// <summary>
/// Clears the heap
/// </summary>
public void Clear()
{
this.count = 0;
}
/// <summary>
/// Clears the heap.
/// </summary>
/// <param name="completeClear">Specifies if the underlying array should be cleared as well</param>
public void Clear(bool completeClear)
{
this.count = 0;
if (completeClear)
{
this.capacity = this.initialCapacity;
this.items = new T[this.initialCapacity];
}
}
/// <summary>
/// Returns an enumerator that iterates over the heap.
/// </summary>
/// <returns>Enumerator that iterates over the heap.</returns>
public IEnumerator<T> GetEnumerator()
{
for (var i = 0; i < this.count; i++)
{
yield return this.items[i + 1];
}
}
#endregion
#region Private Methods
/// <summary>
/// Bubble the specified element to its position
/// </summary>
/// <param name="index">Index of element to bubble</param>
private void BubbleDown(int index)
{
var temp = this.items[index];
int childIndex;
for (; 2 * index <= this.count; index = childIndex)
{
childIndex = 2 * index;
if (childIndex != this.Count && this.items[childIndex].CompareTo(this.items[childIndex + 1]) > 0)
{
childIndex++;
}
if (temp.CompareTo(this.items[childIndex]) > 0)
{
this.items[index] = this.items[childIndex];
}
else
{
break;
}
}
this.items[index] = temp;
}
/// <summary>
/// Implementation of IEnumerator.
/// </summary>
/// <returns>Enumerator over the array.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
File diff suppressed because it is too large Load Diff
@@ -1,39 +1,38 @@
namespace System.Collections.Generic
namespace System.Collections.Generic;
/// <summary>
/// Interface for queue implementations.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
public interface IQueue<T> : IEnumerable<T>
{
/// <summary>
/// Interface for queue implementations.
/// Returns the number of items in the queue.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
public interface IQueue<T> : IEnumerable<T>
{
/// <summary>
/// Returns the number of items in the queue.
/// </summary>
int Count { get; }
/// <summary>
/// Inserts item into the queue.
/// </summary>
/// <param name="item">Item to be inserted.</param>
void Enqueue(T item);
/// <summary>
/// Remove the first item in the queue.
/// </summary>
/// <returns>First item in the queue.</returns>
T Dequeue();
/// <summary>
/// Looks up the first item from the queue without removing it.
/// </summary>
/// <returns>First item from the queue.</returns>
T Peek();
/// <summary>
/// Clears the contents of the queue.
/// </summary>
void Clear();
/// <summary>
/// Checks if queue contains an item.
/// </summary>
/// <param name="item">Item to be checked.</param>
/// <returns>True if queue contains provided item. False otherwise.</returns>
bool Contains(T item);
}
int Count { get; }
/// <summary>
/// Inserts item into the queue.
/// </summary>
/// <param name="item">Item to be inserted.</param>
void Enqueue(T item);
/// <summary>
/// Remove the first item in the queue.
/// </summary>
/// <returns>First item in the queue.</returns>
T Dequeue();
/// <summary>
/// Looks up the first item from the queue without removing it.
/// </summary>
/// <returns>First item from the queue.</returns>
T Peek();
/// <summary>
/// Clears the contents of the queue.
/// </summary>
void Clear();
/// <summary>
/// Checks if queue contains an item.
/// </summary>
/// <param name="item">Item to be checked.</param>
/// <returns>True if queue contains provided item. False otherwise.</returns>
bool Contains(T item);
}
@@ -1,103 +1,102 @@
namespace System.Collections.Generic
namespace System.Collections.Generic;
/// <summary>
/// Priority Queue data structure. The implementation is based on an array-based implementation of Binary Heap.
/// Exposes some of the functionality of the Binary Heap as a queue.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class PriorityQueue<T> : IQueue<T> where T : IComparable<T>
{
#region Fields
private readonly BinaryHeap<T> binaryHeap;
#endregion
#region Properties
/// <summary>
/// Priority Queue data structure. The implementation is based on an array-based implementation of Binary Heap.
/// Exposes some of the functionality of the Binary Heap as a queue.
/// Returns the number of elements stored into the queue.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class PriorityQueue<T> : IQueue<T> where T : IComparable<T>
public int Count
{
#region Fields
private readonly BinaryHeap<T> binaryHeap;
#endregion
#region Properties
/// <summary>
/// Returns the number of elements stored into the queue.
/// </summary>
public int Count
get
{
get
{
return binaryHeap.Count;
}
return this.binaryHeap.Count;
}
#endregion
#region Constructors
/// <summary>
/// Constructor for priority queue data structure.
/// </summary>
public PriorityQueue()
{
binaryHeap = new BinaryHeap<T>();
}
#endregion
#region Public Methods
/// <summary>
/// Add provided value to the queue.
/// </summary>
/// <param name="value">Value to be added to the queue.</param>
public void Enqueue(T value)
{
binaryHeap.Add(value);
}
/// <summary>
/// Pops the queue and removes the highest priority value from the queue.
/// </summary>
/// <returns>Highest priority value from the queue</returns>
public T Dequeue()
{
if (Count > 0)
{
return binaryHeap.Remove();
}
else
{
throw new IndexOutOfRangeException("Queue is empty!");
}
}
/// <summary>
/// Looks up the highest priority value from the queue. Doesn't alter the queue in any way.
/// </summary>
/// <returns>Highest priority value from the queue.</returns>
public T Peek()
{
return binaryHeap.Min;
}
/// <summary>
/// Clears the queue contents, removing any value stored into the queue.
/// </summary>
public void Clear()
{
binaryHeap.Clear();
}
/// <summary>
/// Checks if queue contains provided item.
/// </summary>
/// <param name="item">Item to be checked.</param>
/// <returns>True if queue contains the provided item. False otherwise.</returns>
public bool Contains(T item)
{
return binaryHeap.Contains(item);
}
/// <summary>
/// Returns an enumerator that iterates over the queue.
/// </summary>
/// <returns>Enumerator that iterates over the queue.</returns>
public IEnumerator<T> GetEnumerator()
{
return binaryHeap.GetEnumerator();
}
#endregion
#region Private Methods
/// <summary>
/// Necesarry for the implementatio of IQueue.
/// </summary>
/// <returns></returns>
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
#endregion
#region Constructors
/// <summary>
/// Constructor for priority queue data structure.
/// </summary>
public PriorityQueue()
{
this.binaryHeap = new BinaryHeap<T>();
}
#endregion
#region Public Methods
/// <summary>
/// Add provided value to the queue.
/// </summary>
/// <param name="value">Value to be added to the queue.</param>
public void Enqueue(T value)
{
this.binaryHeap.Add(value);
}
/// <summary>
/// Pops the queue and removes the highest priority value from the queue.
/// </summary>
/// <returns>Highest priority value from the queue</returns>
public T Dequeue()
{
if (this.Count > 0)
{
return this.binaryHeap.Remove();
}
else
{
throw new IndexOutOfRangeException("Queue is empty!");
}
}
/// <summary>
/// Looks up the highest priority value from the queue. Doesn't alter the queue in any way.
/// </summary>
/// <returns>Highest priority value from the queue.</returns>
public T Peek()
{
return this.binaryHeap.Min;
}
/// <summary>
/// Clears the queue contents, removing any value stored into the queue.
/// </summary>
public void Clear()
{
this.binaryHeap.Clear();
}
/// <summary>
/// Checks if queue contains provided item.
/// </summary>
/// <param name="item">Item to be checked.</param>
/// <returns>True if queue contains the provided item. False otherwise.</returns>
public bool Contains(T item)
{
return this.binaryHeap.Contains(item);
}
/// <summary>
/// Returns an enumerator that iterates over the queue.
/// </summary>
/// <returns>Enumerator that iterates over the queue.</returns>
public IEnumerator<T> GetEnumerator()
{
return this.binaryHeap.GetEnumerator();
}
#endregion
#region Private Methods
/// <summary>
/// Necesarry for the implementatio of IQueue.
/// </summary>
/// <returns></returns>
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
@@ -1,236 +1,248 @@
namespace System.Collections.Generic
namespace System.Collections.Generic;
/// <summary>
/// Skip list implementation.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class SkipList<T> : ICollection<T> where T : IComparable<T>
{
/// <summary>
/// Skip list implementation.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
#region Fields
[Serializable]
public sealed class SkipList<T> : ICollection<T> where T : IComparable<T>
private class NodeSet<TKey>
{
#region Fields
[Serializable]
private class NodeSet<TKey>
{
public TKey Key;
public int Level;
public NodeSet<TKey>[] Next;
public TKey Key;
public int Level;
public NodeSet<TKey>[] Next;
public NodeSet(TKey key, int level)
{
this.Key = key;
this.Level = level;
Next = new NodeSet<TKey>[level + 1];
}
}
private int count;
private readonly Random random;
private readonly NodeSet<T> head;
private readonly NodeSet<T> end;
private readonly int maxLevel = 10;
private int level;
#endregion
#region Properties
/// <summary>
/// Number of elements in the list.
/// </summary>
public int Count { get => count; }
/// <summary>
/// Specifies if the collection can be modified.
/// </summary>
public bool IsReadOnly { get; set; }
#endregion
#region Constructors
/// <summary>
/// Creates a new instance of SkipList collection.
/// </summary>
/// <param name="maxLevel">Maximum level of the skip list.</param>
public SkipList(int maxLevel = 10)
public NodeSet(TKey key, int level)
{
this.maxLevel = maxLevel;
random = new Random();
head = new NodeSet<T>(default, maxLevel);
end = head;
for (var i = 0; i <= maxLevel; i++)
{
head.Next[i] = end;
}
this.Key = key;
this.Level = level;
this.Next = new NodeSet<TKey>[level + 1];
}
}
private int count;
private readonly Random random;
private readonly NodeSet<T> head;
private readonly NodeSet<T> end;
private readonly int maxLevel = 10;
private int level;
#endregion
#region Properties
/// <summary>
/// Number of elements in the list.
/// </summary>
public int Count { get => this.count; }
/// <summary>
/// Specifies if the collection can be modified.
/// </summary>
public bool IsReadOnly { get; set; }
#endregion
#region Constructors
/// <summary>
/// Creates a new instance of SkipList collection.
/// </summary>
/// <param name="maxLevel">Maximum level of the skip list.</param>
public SkipList(int maxLevel = 10)
{
this.maxLevel = maxLevel;
this.random = new Random();
this.head = new NodeSet<T>(default, maxLevel);
this.end = this.head;
for (var i = 0; i <= maxLevel; i++)
{
this.head.Next[i] = this.end;
}
}
#endregion
#region Public Methods
/// <summary>
/// Adds an item to the collection.
/// </summary>
/// <param name="item">Item to be added.</param>
public void Add(T item)
{
var curNode = this.head;
var newLevel = 0;
while (this.random.Next(0, 2) > 0 && newLevel < this.maxLevel)
{
newLevel++;
}
#endregion
#region Public Methods
/// <summary>
/// Adds an item to the collection.
/// </summary>
/// <param name="item">Item to be added.</param>
public void Add(T item)
if (newLevel > this.level)
{
var curNode = head;
var newLevel = 0;
while (random.Next(0, 2) > 0 && newLevel < maxLevel)
{
newLevel++;
}
if (newLevel > level)
{
level = newLevel;
}
var newNode = new NodeSet<T>(item, newLevel);
for (var i = 0; i <= newLevel; i++)
{
if (i > curNode.Level)
{
curNode = head;
}
while (curNode.Next[i] != end && curNode.Next[i].Key.CompareTo(item) < 0)
{
curNode = curNode.Next[i];
}
newNode.Next[i] = curNode.Next[i];
curNode.Next[i] = newNode;
}
count++;
this.level = newLevel;
}
/// <summary>
/// Removes provided item from the collection.
/// </summary>
/// <param name="item">Item to be removed.</param>
/// <returns>True if removal was successful.</returns>
public bool Remove(T item)
var newNode = new NodeSet<T>(item, newLevel);
for (var i = 0; i <= newLevel; i++)
{
var removed = false;
var curNode = head;
for (var i = 0; i <= maxLevel; i++)
if (i > curNode.Level)
{
if (i > curNode.Level)
{
curNode = head;
}
while (curNode.Next[i] != end && curNode.Next[i].Key.CompareTo(item) < 0)
{
curNode = curNode.Next[i];
}
if (curNode.Next[i].Key.CompareTo(item) == 0) //Item is present on this level
{
curNode.Next[i] = curNode.Next[i].Next[i];
removed = true;
}
else
{
break;
}
curNode = this.head;
}
if (removed)
while (curNode.Next[i] != this.end && curNode.Next[i].Key.CompareTo(item) < 0)
{
count--;
return true;
curNode = curNode.Next[i];
}
newNode.Next[i] = curNode.Next[i];
curNode.Next[i] = newNode;
}
this.count++;
}
/// <summary>
/// Removes provided item from the collection.
/// </summary>
/// <param name="item">Item to be removed.</param>
/// <returns>True if removal was successful.</returns>
public bool Remove(T item)
{
var removed = false;
var curNode = this.head;
for (var i = 0; i <= this.maxLevel; i++)
{
if (i > curNode.Level)
{
curNode = this.head;
}
while (curNode.Next[i] != this.end && curNode.Next[i].Key.CompareTo(item) < 0)
{
curNode = curNode.Next[i];
}
if (curNode.Next[i].Key.CompareTo(item) == 0) //Item is present on this level
{
curNode.Next[i] = curNode.Next[i].Next[i];
removed = true;
}
else
{
return false;
break;
}
}
/// <summary>
/// Clears the collection.
/// </summary>
public void Clear()
if (removed)
{
for (var i = 0; i < maxLevel; i++)
{
head.Next[i] = end;
}
count = 0;
this.count--;
return true;
}
/// <summary>
/// Checks if item is present in the collection.
/// </summary>
/// <param name="item">Item to be checked.</param>
/// <returns>True if item is present in the collection.</returns>
public bool Contains(T item)
else
{
if (Find(item) != null)
{
return true;
}
return false;
}
/// <summary>
/// Copies the skip list contents onto the provided array.
/// </summary>
/// <param name="array">Array to hold the values from the list.</param>
/// <param name="arrayIndex">Index to start insertion in the array.</param>
public void CopyTo(T[] array, int arrayIndex)
{
var node = head.Next[0];
while (node != end)
{
array[arrayIndex] = node.Key;
arrayIndex++;
node = node.Next[0];
}
}
/// <summary>
/// Copies the elements from the collection into an array.
/// </summary>
/// <returns>Array filled with elements from the collection.</returns>
public T[] ToArray()
{
var array = new T[count];
var index = 0;
var curNode = head.Next[0];
while (curNode != end)
{
array[index] = curNode.Key;
index++;
curNode = curNode.Next[0];
}
return array;
}
/// <summary>
/// Enumerator that iterates over the collection.
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
var curNode = head.Next[0];
while (curNode != end)
{
yield return curNode.Key;
curNode = curNode.Next[0];
}
}
#endregion
#region Private Methods
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
private NodeSet<T> Find(T key)
{
var curNode = head;
for (var i = level; i >= 0; i--)
{
while (curNode.Next[i] != end)
{
if (curNode.Next[i].Key.CompareTo(key) > 0)
{
break;
}
else if (curNode.Next[i].Key.CompareTo(key) == 0)
{
return curNode.Next[i];
}
curNode = curNode.Next[i];
}
}
curNode = curNode.Next[0];
if (curNode != end && curNode.Key.CompareTo(key) == 0)
{
return curNode;
}
return null;
}
#endregion
}
/// <summary>
/// Clears the collection.
/// </summary>
public void Clear()
{
for (var i = 0; i < this.maxLevel; i++)
{
this.head.Next[i] = this.end;
}
this.count = 0;
}
/// <summary>
/// Checks if item is present in the collection.
/// </summary>
/// <param name="item">Item to be checked.</param>
/// <returns>True if item is present in the collection.</returns>
public bool Contains(T item)
{
if (this.Find(item) != null)
{
return true;
}
return false;
}
/// <summary>
/// Copies the skip list contents onto the provided array.
/// </summary>
/// <param name="array">Array to hold the values from the list.</param>
/// <param name="arrayIndex">Index to start insertion in the array.</param>
public void CopyTo(T[] array, int arrayIndex)
{
var node = this.head.Next[0];
while (node != this.end)
{
array[arrayIndex] = node.Key;
arrayIndex++;
node = node.Next[0];
}
}
/// <summary>
/// Copies the elements from the collection into an array.
/// </summary>
/// <returns>Array filled with elements from the collection.</returns>
public T[] ToArray()
{
var array = new T[this.count];
var index = 0;
var curNode = this.head.Next[0];
while (curNode != this.end)
{
array[index] = curNode.Key;
index++;
curNode = curNode.Next[0];
}
return array;
}
/// <summary>
/// Enumerator that iterates over the collection.
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
var curNode = this.head.Next[0];
while (curNode != this.end)
{
yield return curNode.Key;
curNode = curNode.Next[0];
}
}
#endregion
#region Private Methods
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
private NodeSet<T> Find(T key)
{
var curNode = this.head;
for (var i = this.level; i >= 0; i--)
{
while (curNode.Next[i] != this.end)
{
if (curNode.Next[i].Key.CompareTo(key) > 0)
{
break;
}
else if (curNode.Next[i].Key.CompareTo(key) == 0)
{
return curNode.Next[i];
}
curNode = curNode.Next[i];
}
}
curNode = curNode.Next[0];
if (curNode != this.end && curNode.Key.CompareTo(key) == 0)
{
return curNode;
}
return null;
}
#endregion
}
+280 -273
View File
@@ -1,280 +1,287 @@
namespace System.Collections.Generic
namespace System.Collections.Generic;
/// <summary>
/// Treap implementation.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
[Serializable]
public sealed class Treap<T> : ICollection<T> where T : IComparable<T>
{
/// <summary>
/// Treap implementation.
/// </summary>
/// <typeparam name="T">Provided type.</typeparam>
#region Fields
[Serializable]
public sealed class Treap<T> : ICollection<T> where T : IComparable<T>
private class Node<TKey>
{
#region Fields
[Serializable]
private class Node<TKey>
public TKey Key;
public int Priority;
public Node<TKey> Left, Right;
public Node(TKey key, int priority)
{
public TKey Key;
public int Priority;
public Node<TKey> Left, Right;
public Node(TKey key, int priority)
{
Key = key;
Priority = priority;
Left = null;
Right = null;
}
this.Key = key;
this.Priority = priority;
this.Left = null;
this.Right = null;
}
private readonly Random randomGen;
private Node<T> root;
private int count;
#endregion
#region Properties
/// <summary>
/// Count of values in the treap.
/// </summary>
public int Count
{
get
{
return count;
}
}
/// <summary>
/// Not implemented.
/// </summary>
public bool IsReadOnly => false;
#endregion
#region Constructors
/// <summary>
/// Constructor for treap.
/// </summary>
public Treap()
{
randomGen = new Random();
}
#endregion
#region Public Methods
/// <summary>
/// Adds value to the treap.
/// </summary>
/// <param name="value">Value to be added.</param>
public void Add(T value)
{
root = InsertNode(root, value);
count++;
}
/// <summary>
/// Removes value from treap.
/// </summary>
/// <param name="value">Value to be removed.</param>
public bool Remove(T value)
{
root = RemoveNode(root, value);
count--;
return true;
}
/// <summary>
/// Clears the treap.
/// </summary>
public void Clear()
{
Clear(root);
root = null;
count = 0;
}
/// <summary>
/// Determines whether the treap contains the specified value.
/// </summary>
/// <param name="value">Value to locate in the treap.</param>
/// <returns></returns>
public bool Contains(T value)
{
return Find(root, value) != null;
}
/// <summary>
/// Returns the treap structure as an ordered array.
/// </summary>
/// <returns>Ordered array containing the values stored in the treap.</returns>
public T[] ToArray()
{
if (root != null)
{
var array = new T[count];
var index = 0;
ToArray(root, ref array, ref index);
return array;
}
else
{
return null;
}
}
/// <summary>
/// Copy the treap into the provided array.
/// </summary>
/// <param name="array">Array to be populated with the values contained in the array.</param>
/// <param name="arrayIndex">Starting index of the array.</param>
public void CopyTo(T[] array, int arrayIndex)
{
ToArray(root, ref array, ref arrayIndex);
}
/// <summary>
/// Enumerator that iterates over the treap. Note that the values are not guaranteed to be sorted.
/// </summary>
/// <returns>Enumerator that iterates over the treap.</returns>
public IEnumerator<T> GetEnumerator()
{
return GetEnumerator(root);
}
#endregion
#region Private Methods
private Node<T> InsertNode(Node<T> node, T key)
{
if (node == null)
{
node = new Node<T>(key, randomGen.Next(0, 100));
return node;
}
else if (key.CompareTo(node.Key) <= 0)
{
node.Left = InsertNode(node.Left, key);
if (node.Left.Priority > node.Priority)
{
node = RotateRight(node);
}
}
else
{
node.Right = InsertNode(node.Right, key);
if (node.Right.Priority > node.Priority)
{
node = RotateLeft(node);
}
}
return node;
}
private Node<T> RemoveNode(Node<T> node, T key)
{
if (node == null)
{
return node;
}
if (key.CompareTo(node.Key) < 0)
{
node.Left = RemoveNode(node.Left, key);
}
else if (key.CompareTo(node.Key) > 0)
{
node.Right = 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 = RotateLeft(node);
node.Left = RemoveNode(node.Left, key);
}
else
{
node = RotateRight(node);
node.Right = RemoveNode(node.Right, key);
}
return node;
}
private Node<T> RotateRight(Node<T> node)
{
Node<T> temp = node.Left, temp2 = temp.Right;
temp.Right = node;
node.Left = temp2;
return temp;
}
private Node<T> RotateLeft(Node<T> node)
{
Node<T> temp = node.Right, temp2 = temp.Left;
temp.Left = node;
node.Right = temp2;
return temp;
}
private void Clear(Node<T> node)
{
if (node.Left != null)
{
Clear(node.Left);
}
if (node.Right != null)
{
Clear(node.Right);
}
node.Left = node.Right = null;
}
private Node<T> Find(Node<T> node, T key)
{
if (node == null)
{
return node;
}
else
{
if (node.Key.CompareTo(key) < 0)
{
var found = Find(node.Left, key);
if (found == null)
{
found = Find(node.Right, key);
}
return found;
}
else if (node.Key.CompareTo(key) > 0)
{
var found = Find(node.Right, key);
if (found == null)
{
found = Find(node.Left, key);
}
return found;
}
else
{
return node;
}
}
}
private void ToArray(Node<T> node, ref T[] array, ref int index)
{
if (node != null)
{
ToArray(node.Left, ref array, ref index);
array[index] = node.Key;
index++;
ToArray(node.Right, ref array, ref index);
}
}
private IEnumerator<T> GetEnumerator(Node<T> currentNode)
{
var queue = new Queue<Node<T>>();
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
}
private readonly Random randomGen;
private Node<T> root;
private int count;
#endregion
#region Properties
/// <summary>
/// Count of values in the treap.
/// </summary>
public int Count
{
get
{
return this.count;
}
}
/// <summary>
/// Not implemented.
/// </summary>
public bool IsReadOnly => false;
#endregion
#region Constructors
/// <summary>
/// Constructor for treap.
/// </summary>
public Treap()
{
this.randomGen = new Random();
}
#endregion
#region Public Methods
/// <summary>
/// Adds value to the treap.
/// </summary>
/// <param name="value">Value to be added.</param>
public void Add(T value)
{
this.root = this.InsertNode(this.root, value);
this.count++;
}
/// <summary>
/// Removes value from treap.
/// </summary>
/// <param name="value">Value to be removed.</param>
public bool Remove(T value)
{
this.root = this.RemoveNode(this.root, value);
this.count--;
return true;
}
/// <summary>
/// Clears the treap.
/// </summary>
public void Clear()
{
this.Clear(this.root);
this.root = null;
this.count = 0;
}
/// <summary>
/// Determines whether the treap contains the specified value.
/// </summary>
/// <param name="value">Value to locate in the treap.</param>
/// <returns></returns>
public bool Contains(T value)
{
return this.Find(this.root, value) != null;
}
/// <summary>
/// Returns the treap structure as an ordered array.
/// </summary>
/// <returns>Ordered array containing the values stored in the treap.</returns>
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 null;
}
}
/// <summary>
/// Copy the treap into the provided array.
/// </summary>
/// <param name="array">Array to be populated with the values contained in the array.</param>
/// <param name="arrayIndex">Starting index of the array.</param>
public void CopyTo(T[] array, int arrayIndex)
{
this.ToArray(this.root, ref array, ref arrayIndex);
}
/// <summary>
/// Enumerator that iterates over the treap. Note that the values are not guaranteed to be sorted.
/// </summary>
/// <returns>Enumerator that iterates over the treap.</returns>
public IEnumerator<T> GetEnumerator()
{
return this.GetEnumerator(this.root);
}
#endregion
#region Private Methods
private Node<T> InsertNode(Node<T> node, T key)
{
if (node == null)
{
node = new Node<T>(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<T> RemoveNode(Node<T> 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<T> RotateRight(Node<T> node)
{
Node<T> temp = node.Left, temp2 = temp.Right;
temp.Right = node;
node.Left = temp2;
return temp;
}
private Node<T> RotateLeft(Node<T> node)
{
Node<T> temp = node.Right, temp2 = temp.Left;
temp.Left = node;
node.Right = temp2;
return temp;
}
private void Clear(Node<T> node)
{
if (node.Left != null)
{
this.Clear(node.Left);
}
if (node.Right != null)
{
this.Clear(node.Right);
}
node.Left = node.Right = null;
}
private Node<T> Find(Node<T> 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<T> 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<T> GetEnumerator(Node<T> currentNode)
{
var queue = new Queue<Node<T>>();
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
}