Implemented Fibonacci Heap + Tests

This commit is contained in:
Alex Macocian
2019-04-18 15:41:50 +02:00
parent f15855dec4
commit afdfeda826
9 changed files with 1230 additions and 6 deletions
+4 -4
View File
@@ -78,10 +78,10 @@ namespace SystemExtensions.Collections
items[position] = value;
}
/// <summary>
/// Deletes the item at the root. Throws exception if there are no items in the heap.
/// Removes the item at the root. Throws exception if there are no items in the heap.
/// </summary>
/// <returns></returns>
public T DeleteMin()
/// <returns>Value removed.</returns>
public T RemoveMin()
{
if (count == 0)
{
@@ -93,7 +93,7 @@ namespace SystemExtensions.Collections
return min;
}
/// <summary>
/// Function to return the heap structure as an array
/// Return the heap structure as an array
/// </summary>
/// <returns>Array with values sorted as in heap</returns>
public T[] ToArray()
@@ -0,0 +1,549 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SystemExtensions.Collections
{
public class FibonacciHeap<T> : IDisposable
{
#region Fields
private FibonacciNode<T> root;
private Comparison<T> comparator;
private int count;
#endregion
#region Properties
/// <summary>
/// Count of values in the heap.
/// </summary>
public int Count
{
get
{
return count;
}
}
/// <summary>
/// Minimal value contained in the heap.
/// </summary>
public T Minimum
{
get
{
return root.Value;
}
}
#endregion
#region Constructors
public FibonacciHeap(Comparison<T> comparator)
{
this.comparator = comparator;
}
#endregion
#region Public Methods
/// <summary>
/// Inserts value into the heap.
/// </summary>
/// <param name="value">Value to be inserted.</param>
public void Insert(T value)
{
FibonacciNode<T> node = new FibonacciNode<T>();
node.Value = value;
node.Previous = node.Next = node;
node.Degree = 0;
node.Marked = false;
node.Child = null;
node.Parent = null;
root = Merge(root, node);
count++;
}
/// <summary>
/// Merge current heap with another heap. The other heap will be disposed at the end of this method.
/// </summary>
/// <param name="otherHeap">The heap to be merged with the current heap.</param>
public void Merge(FibonacciHeap<T> otherHeap)
{
root = Merge(root, otherHeap.root);
otherHeap.root = null;
count += otherHeap.count;
otherHeap.Dispose();
}
/// <summary>
/// Remove the minimum value from the heap.
/// </summary>
/// <returns>Minimum value.</returns>
public T RemoveMinimum()
{
FibonacciNode<T> currentRoot = root;
if (currentRoot != null)
{
root = RemoveMinimum(root);
count--;
return currentRoot.Value;
}
else
{
throw new IndexOutOfRangeException("Heap is empty!");
}
}
/// <summary>
/// Decrease the old value to a new provided value.
/// </summary>
/// <param name="oldValue">Old value used to find the node to have its key decreased.</param>
/// <param name="value">New value to be assigned to the node.</param>
public void DecreaseKey(T oldValue, T value)
{
FibonacciNode<T> node = Find(root, oldValue);
root = DecreaseKey(root, node, value);
}
/// <summary>
/// Determines whether the heap contains a specified value.
/// </summary>
/// <param name="value">Valye to locate in the heap.</param>
/// <returns></returns>
public bool Contains(T value)
{
return Find(root, value) != null;
}
/// <summary>
/// Clears the heap.
/// </summary>
public void Clear()
{
count = 0;
Remove(root);
root.Next = root.Previous = root.Parent = root.Child = null;
root = null;
}
/// <summary>
/// Return the heap structure as an array. Array is not sorted other than the
/// actual structure of the heap.
/// </summary>
/// <returns>Array with values from the heap.</returns>
public T[] ToArray()
{
if(count == 0)
{
return null;
}
T[] array = new T[count];
if (count == 1)
{
array[0] = root.Value;
return array;
}
else
{
int index = 0;
RecursiveFillArray(root, ref array, ref index);
return array;
}
}
#endregion
#region Private Methods
/// <summary>
/// Recursively traverse the heap and copy its contents to an array.
/// </summary>
/// <param name="currentNode">Current node.</param>
/// <param name="array">Array to be filled with contents of heap.</param>
/// <param name="index">Index of the next unintialized element in the array.</param>
private void RecursiveFillArray(FibonacciNode<T> currentNode, ref T[] array, ref int index)
{
FibonacciNode<T> oldNode = currentNode;
do
{
array[index] = currentNode.Value;
index++;
if (currentNode.HasChildren())
{
RecursiveFillArray(currentNode.Child, ref array, ref index);
}
currentNode = currentNode.Previous;
} while (currentNode != oldNode);
}
/// <summary>
/// Recursively remove the node and its children from the heap.
/// </summary>
/// <param name="node">Node to be removed.</param>
private void Remove(FibonacciNode<T> node)
{
if(node != null)
{
FibonacciNode<T> current = node;
do
{
Remove(current.Child);
if (current.Parent != null)
{
current.Parent.Child = null;
}
current = current.Next;
} while (current != node);
current.Next = current.Previous = current.Child = current.Parent = null;
}
}
/// <summary>
/// Merge two heaps into a larger heap.
/// </summary>
/// <param name="node1">Root of first heap.</param>
/// <param name="node2">Root of second heap.</param>
private FibonacciNode<T> Merge(FibonacciNode<T> node1, FibonacciNode<T> node2)
{
if(node1 == null)
{
return node2;
}
if(node2 == null)
{
return node1;
}
if(comparator(node1.Value, node2.Value) > 0)
{
FibonacciNode<T> temp = node1;
node1 = node2;
node2 = temp;
}
FibonacciNode<T> node1Next = node1.Next;
FibonacciNode<T> node2Prev = node2.Previous;
node1.Next = node2;
node2.Previous = node1;
node1Next.Previous = node2Prev;
node2Prev.Next = node1Next;
return node1;
}
/// <summary>
/// Adds child to the parent.
/// </summary>
/// <param name="parent">Parent node to accept child.</param>
/// <param name="child">Child node to be added to the parent.</param>
private void AddChild(FibonacciNode<T> parent, FibonacciNode<T> child)
{
child.Previous = child.Next = child;
child.Parent = parent;
parent.Degree++;
parent.Child = Merge(parent.Child, child);
}
/// <summary>
/// Removes the parent of the specified node.
/// </summary>
/// <param name="node">Node to be removed from its parent.</param>
private void RemoveParent(FibonacciNode<T> node)
{
if(node == null)
{
return;
}
FibonacciNode<T> current = node;
do
{
current.Marked = false;
current.Parent = null;
current = current.Next;
} while (current != node);
}
/// <summary>
/// Removes the minimum node from the provided tree.
/// </summary>
/// <param name="node">Root of the provided tree.</param>
/// <returns></returns>
private FibonacciNode<T> RemoveMinimum(FibonacciNode<T> node)
{
RemoveParent(node.Child);
if(node.Next == node)
{
node = node.Child;
}
else
{
node.Next.Previous = node.Previous;
node.Previous.Next = node.Next;
node = Merge(node.Next, node.Child);
}
if(node == null)
{
return node;
}
FibonacciNode<T>[] trees = new FibonacciNode<T>[64];
while (true)
{
if(trees[node.Degree] != null)
{
FibonacciNode<T> t = trees[node.Degree];
if(t == node)
{
break;
}
trees[node.Degree] = null;
if(comparator(node.Value, t.Value) < 0)
{
t.Previous.Next = t.Next;
t.Next.Previous = t.Previous;
AddChild(node, t);
}
else
{
t.Previous.Next = t.Next;
t.Next.Previous = t.Previous;
if(node.Next == node)
{
t.Next = t.Previous = t;
AddChild(t, node);
node = t;
}
else
{
node.Previous.Next = t;
node.Next.Previous = t;
t.Next = node.Next;
t.Previous = node.Previous;
AddChild(t, node);
node = t;
}
}
continue;
}
else
{
trees[node.Degree] = node;
}
node = node.Next;
}
FibonacciNode<T> min = node;
FibonacciNode<T> start = node;
do
{
if(comparator(node.Value, min.Value) < 0)
{
min = node;
}
node = node.Next;
} while (node != start);
return min;
}
/// <summary>
/// Cut node from heap.
/// </summary>
/// <param name="root">Root of heap.</param>
/// <param name="node">Node to be cut.</param>
/// <returns></returns>
private FibonacciNode<T> Cut(FibonacciNode<T> root, FibonacciNode<T> node)
{
if(node.Next == node)
{
node.Parent.Child = null;
}
else
{
node.Next.Previous = node.Previous;
node.Previous.Next = node.Next;
node.Parent.Child = node.Next;
}
node.Next = node.Previous = node;
node.Marked = false;
return Merge(root, node);
}
/// <summary>
/// Decrease value of provided node substituting it with the provided value.
/// </summary>
/// <param name="root">Root of the heap.</param>
/// <param name="node">Node to have value decreased.</param>
/// <param name="value">New value of the node. It is only applied if the value is lower than the previous value.</param>
/// <returns></returns>
private FibonacciNode<T> DecreaseKey(FibonacciNode<T> root, FibonacciNode<T> node, T value)
{
if(comparator(node.Value, value) < 0)
{
return root;
}
node.Value = value;
if(node.Parent != null)
{
if(comparator(node.Value, node.Parent.Value) < 0)
{
root = Cut(root, node);
FibonacciNode<T> parent = node.Parent;
node.Parent = null;
while(parent != null && parent.Marked)
{
root = Cut(root, parent);
node = parent;
parent = node.Parent;
node.Parent = null;
}
if(parent != null && parent.Parent != null)
{
parent.Marked = true;
}
}
}
else
{
if(comparator(node.Value, root.Value) < 0)
{
root = node;
}
}
return root;
}
/// <summary>
/// Find the node that has the specified value in the heap.
/// </summary>
/// <param name="root">Root of the heap.</param>
/// <param name="value">Value to be found.</param>
/// <returns></returns>
private FibonacciNode<T> Find(FibonacciNode<T> root, T value)
{
FibonacciNode<T> node = root;
if(node == null)
{
return null;
}
do
{
if(comparator(node.Value, value) == 0)
{
return node;
}
FibonacciNode<T> ret = Find(node.Child, value);
if(ret != null)
{
return ret;
}
node = node.Next;
} while (node != root);
return null;
}
#endregion
#region IDisposable Support
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (root != null)
{
if (disposing)
{
Remove(root);
}
root.Previous = root.Next = root.Parent = root.Child = null;
root = null;
}
disposedValue = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
internal class FibonacciNode<T>
{
#region Fields
private FibonacciNode<T> previous;
private FibonacciNode<T> next;
private FibonacciNode<T> child;
private FibonacciNode<T> parent;
private T value;
private int degree;
private bool marked;
#endregion
#region Properties
public FibonacciNode<T> Previous
{
get
{
return previous;
}
set
{
previous = value;
}
}
public FibonacciNode<T> Next
{
get
{
return next;
}
set
{
next = value;
}
}
public FibonacciNode<T> Child
{
get
{
return child;
}
set
{
child = value;
}
}
public FibonacciNode<T> Parent
{
get
{
return parent;
}
set
{
parent = value;
}
}
public bool Marked
{
get
{
return marked;
}
set
{
marked = value;
}
}
public T Value
{
get
{
return value;
}
set
{
this.value = value;
}
}
public int Degree
{
get
{
return degree;
}
set
{
degree = value;
}
}
#endregion
#region Public Methods
public bool HasChildren()
{
return child != null;
}
public bool HasParent()
{
return parent != null;
}
#endregion
}
}
@@ -39,7 +39,7 @@ namespace SystemExtensions.Collections
{
if (Count > 0)
{
return binaryHeap.DeleteMin();
return binaryHeap.RemoveMin();
}
else
{
+467
View File
@@ -0,0 +1,467 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SystemExtensions
{
public static class Comparators
{
#region Fields
private static Comparison<int> intComparison = new Comparison<int>(IntegerComparison);
private static Comparison<float> floatComparison = new Comparison<float>(FloatComparison);
private static Comparison<double> doubleComparison = new Comparison<double>(DoubleComparison);
private static Comparison<bool> boolComparison = new Comparison<bool>(BoolComparison);
private static Comparison<decimal> decimalComparison = new Comparison<decimal>(DecimalComparison);
private static Comparison<byte> byteComparison = new Comparison<byte>(ByteComparison);
private static Comparison<long> longComparison = new Comparison<long>(LongComparison);
private static Comparison<uint> uintComparison = new Comparison<uint>(UintComparison);
private static Comparison<Int16> int16Comparison = new Comparison<Int16>(Int16Comparison);
private static Comparison<Int32> int32Comparison = new Comparison<Int32>(Int32Comparison);
private static Comparison<Int64> int64Comparison = new Comparison<Int64>(int64Comparison);
private static Comparison<UInt16> uInt16Comparison = new Comparison<UInt16>(uInt16Comparison);
private static Comparison<UInt32> uInt32Comparison = new Comparison<UInt32>(uInt32Comparison);
private static Comparison<UInt64> uInt64Comparison = new Comparison<UInt64>(uInt64Comparison);
#endregion
#region Properties
/// <summary>
/// Comparison between two ints.
/// </summary>
public static Comparison<int> Int
{
get
{
return intComparison;
}
}
/// <summary>
/// Comparison between two floats.
/// </summary>
public static Comparison<float> Float
{
get
{
return floatComparison;
}
}
/// <summary>
/// Comparison between two doubles.
/// </summary>
public static Comparison<double> Double
{
get
{
return doubleComparison;
}
}
/// <summary>
/// Comparison between two decimals.
/// </summary>
public static Comparison<decimal> Decimal
{
get
{
return decimalComparison;
}
}
/// <summary>
/// Comparison between two bools.
/// </summary>
public static Comparison<bool> Bool
{
get
{
return boolComparison;
}
}
/// <summary>
/// Comparison between two bytes.
/// </summary>
public static Comparison<byte> Byte
{
get
{
return byteComparison;
}
}
/// <summary>
/// Comparison between two longs.
/// </summary>
public static Comparison<long> Long
{
get
{
return longComparison;
}
}
/// <summary>
/// Comparison between two uints.
/// </summary>
public static Comparison<uint> Uint
{
get
{
return uintComparison;
}
}
/// <summary>
/// Comparison between two int16.
/// </summary>
public static Comparison<Int16> Int16
{
get
{
return int16Comparison;
}
}
/// <summary>
/// Comparison between two int32.
/// </summary>
public static Comparison<Int32> Int32
{
get
{
return int32Comparison;
}
}
/// <summary>
/// Comparison between two int64.
/// </summary>
public static Comparison<Int64> Int64
{
get
{
return int64Comparison;
}
}
/// <summary>
/// Comparison between two uint16.
/// </summary>
public static Comparison<UInt16> UInt16
{
get
{
return uInt16Comparison;
}
}
/// <summary>
/// Comparison between two uint32.
/// </summary>
public static Comparison<UInt32> UInt32
{
get
{
return uInt32Comparison;
}
}
/// <summary>
/// Comparison between two uint64.
/// </summary>
public static Comparison<UInt64> UInt64
{
get
{
return uInt64Comparison;
}
}
#endregion
#region Private Methods
/// <summary>
/// Compares two UInt64.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int Uint64Comparison(UInt64 x, UInt64 y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two UInt32.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int Uint32Comparison(UInt32 x, UInt32 y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two UInt16.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int Uint16Comparison(UInt16 x, UInt16 y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Int64.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int Int64Comparison(Int64 x, Int64 y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two UInt32.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int Int32Comparison(Int32 x, Int32 y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two UInt16.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int Int16Comparison(Int16 x, Int16 y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two uint.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int UintComparison(uint x, uint y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Long.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int LongComparison(long x, long y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Byte.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int ByteComparison(byte x, byte y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Decimal.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int DecimalComparison(decimal x, decimal y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Bool.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x is true and y is false. 0 if they are the same and -1
/// if y is true and x is false.</returns>
private static int BoolComparison(bool x, bool y)
{
if (x == y)
{
return 0;
}
else if (x == true && y == false)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Double.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int DoubleComparison(double x, double y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Float.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int FloatComparison(float x, float y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
/// <summary>
/// Compares two Integer.
/// </summary>
/// <param name="x">First value.</param>
/// <param name="y">Second value.</param>
/// <returns>Returns 1 if x > y. 0 if equal and -1 if y > x.</returns>
private static int IntegerComparison(int x, int y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
#endregion
}
}
+2
View File
@@ -42,7 +42,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Collections\BinaryHeap.cs" />
<Compile Include="Collections\FibonacciHeap.cs" />
<Compile Include="Collections\PriorityQueue.cs" />
<Compile Include="Comparators.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Threading\PriorityThreadPool.cs" />
</ItemGroup>
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SystemExtensions;
namespace SystemExtensions.Collections.Tests
{
@@ -77,7 +78,7 @@ namespace SystemExtensions.Collections.Tests
{
Assert.Fail();
}
System.Diagnostics.Debug.WriteLine(binaryHeap.DeleteMin());
System.Diagnostics.Debug.WriteLine(binaryHeap.RemoveMin());
tries--;
}
}
@@ -0,0 +1,203 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SystemExtensions.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace SystemExtensions.Collections.Tests
{
[TestClass()]
public class FibonacciHeapTests
{
private static int IntegerComparison(int x, int y)
{
if (x == y)
{
return 0;
}
else if (x > y)
{
return 1;
}
else
{
return -1;
}
}
FibonacciHeap<int> fibonacciHeap = new FibonacciHeap<int>(new Comparison<int>(IntegerComparison));
[TestMethod()]
public void InsertTest()
{
for (int i = 0; i < 1000; i++)
{
fibonacciHeap.Insert(i);
}
if (fibonacciHeap.RemoveMinimum() != 0)
{
Assert.Fail();
}
for (int i = 1; i < 1000; i++)
{
if (!fibonacciHeap.Contains(i))
{
Assert.Fail();
}
}
}
[TestMethod()]
public void FibonacciHeapTest()
{
fibonacciHeap.Dispose();
fibonacciHeap = new FibonacciHeap<int>(new Comparison<int>(IntegerComparison));
if(fibonacciHeap.Count != 0)
{
Assert.Fail();
}
}
[TestMethod()]
public void MergeTest()
{
fibonacciHeap.Dispose();
FibonacciHeap<int> fibonacciHeap1 = new FibonacciHeap<int>(new Comparison<int>(IntegerComparison));
FibonacciHeap<int> fibonacciHeap2 = new FibonacciHeap<int>(new Comparison<int>(IntegerComparison));
for(int i = 0; i < 100; i++)
{
fibonacciHeap1.Insert(i);
}
for(int i = 100; i < 300; i++)
{
fibonacciHeap2.Insert(i);
}
fibonacciHeap1.Merge(fibonacciHeap2);
for(int i = 1; i < 300; i++)
{
if (!fibonacciHeap1.Contains(i))
{
Assert.Fail();
}
}
}
[TestMethod()]
public void RemoveMinimumTest()
{
try
{
fibonacciHeap.RemoveMinimum();
Assert.Fail();
}
catch(IndexOutOfRangeException exception)
{
}
catch(Exception e)
{
Assert.Fail();
}
for (int i = 0; i < 1000; i++)
{
fibonacciHeap.Insert(i);
}
for (int i = 0; i < 1000; i++)
{
if (fibonacciHeap.RemoveMinimum() != i)
{
Assert.Fail();
}
}
}
[TestMethod()]
public void DecreaseKeyTest()
{
fibonacciHeap.Insert(5);
fibonacciHeap.Insert(10);
fibonacciHeap.Insert(7);
fibonacciHeap.DecreaseKey(5, 3);
if(fibonacciHeap.Contains(5) || !fibonacciHeap.Contains(3))
{
Assert.Fail();
}
fibonacciHeap.DecreaseKey(10, 1);
if(fibonacciHeap.RemoveMinimum() != 1)
{
Assert.Fail();
}
}
[TestMethod()]
public void ContainsTest()
{
for(int i = 0; i < 10000; i++)
{
fibonacciHeap.Insert(i);
}
if (!fibonacciHeap.Contains(5124))
{
Assert.Fail();
}
}
[TestMethod()]
public void ClearTest()
{
for(int i = 0; i < 10000; i++)
{
fibonacciHeap.Insert(i);
}
fibonacciHeap.RemoveMinimum();
fibonacciHeap.Clear();
if(fibonacciHeap.Count > 0)
{
Assert.Fail();
}
}
[TestMethod()]
public void DisposeTest()
{
List<FibonacciHeap<int>> heaps = new List<Collections.FibonacciHeap<int>>();
for(int i = 0; i < 10; i++)
{
heaps.Add(new Collections.FibonacciHeap<int>(new Comparison<int>(IntegerComparison)));
for(int j = 0; j < 10000; j++)
{
heaps[heaps.Count - 1].Insert(j);
}
}
for(int i = 0; i < 10; i++)
{
heaps[i].Dispose();
}
GC.Collect();
heaps.Clear();
}
[TestMethod()]
public void ToArrayTest()
{
for(int i = 999; i >= 0; i--)
{
fibonacciHeap.Insert(i);
}
fibonacciHeap.RemoveMinimum();
int[] arr = fibonacciHeap.ToArray();
for(int i = 1; i < 512; i++)
{
if(arr[i - 1] != i)
{
Assert.Fail();
}
}
}
}
}
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SystemExtensions;
namespace SystemExtensions.Collections.Tests
{
@@ -57,6 +57,7 @@
</Choose>
<ItemGroup>
<Compile Include="Collections\BinaryHeapTests.cs" />
<Compile Include="Collections\FibonacciHeapTests.cs" />
<Compile Include="Collections\PriorityQueueTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Threading\PriorityThreadPoolTests.cs" />