static BinomialHeap<int> BuildHeap(params int[] data) { var heap = new BinomialHeap<int>(int.MinValue, Comparer<int>.Default); foreach(var t in data) heap.Insert(t); return heap; }
public void union(BinomialHeap heapToUnite) { this.merge(heapToUnite); if (this.Head == null) { return; } Node previousRoot = null; Node currentRoot = this.Head; Node nextRoot = currentRoot.Sibling; while (nextRoot != null) { /* * Przechodzimy dalej jeśli: * - stopień aktualnego korzenia jest mniejszy od kolejnego (są w prawidłowej kolejności) * - aktualny korzeń jest pierwszym z trzech kolejnych korzeni o tym samym stopniu */ if ((currentRoot.Degree != nextRoot.Degree) || (nextRoot.Sibling != null && currentRoot.Degree == nextRoot.Sibling.Degree)) { previousRoot = currentRoot; currentRoot = nextRoot; } else { /* * W przeciwnym wypadku: * - jeśli stopnie aktualnego i następnego korzenia są równe: * - jeśli klucz aktualnego korzenia(a) jest MNIEJSZY od klucza następnego korzenia(b) - b staje się dzieckiem a * - jeśli klucz aktualnego korzenia jest WIĘKSZY od klucza następnego korzenia - a staje się dzieckiem b */ if (currentRoot.Key <= nextRoot.Key) { currentRoot.Sibling = nextRoot.Sibling; link(nextRoot, currentRoot); } else { if (previousRoot == null) { this.Head = nextRoot; } else { previousRoot.Sibling = nextRoot; } link(currentRoot, nextRoot); currentRoot = nextRoot; } } nextRoot = currentRoot.Sibling; } }
private void merge(BinomialHeap heapToMerge) { Node head1 = this.Head; Node head2 = heapToMerge.Head; Node headOfHeap = null; Node tailOfHeap = null; if (head1.Degree < head2.Degree) { headOfHeap = head1; head1 = head1.Sibling; } else { headOfHeap = head2; head2 = head2.Sibling; } tailOfHeap = headOfHeap; while (head1 != null && head2 != null) { if (head1.Degree < head2.Degree) { tailOfHeap.Sibling = head1; head1 = head1.Sibling; } else { tailOfHeap.Sibling = head2; head2 = head2.Sibling; } tailOfHeap = tailOfHeap.Sibling; } if (head1 != null) { tailOfHeap.Sibling = head1; } else if (head2 != null) { tailOfHeap.Sibling = head2; } else { tailOfHeap.Sibling = null; } this.Head = headOfHeap; }
static void TestCase1() { var heap = new BinomialHeap<int>(int.MinValue, Comparer<int>.Default); heap.Insert(4); heap.Insert(2); heap.Insert(7); heap.Insert(1); heap.Insert(9); Assert(heap.ExtractMin().Item2 == 1); Assert(heap.ExtractMin().Item2 == 2); Assert(heap.ExtractMin().Item2 == 4); Assert(heap.ExtractMin().Item2 == 7); Assert(heap.ExtractMin().Item2 == 9); Assert(!heap.ExtractMin().Item1); }
public bool insert(int value) { if (value > 0) { Node tmpNode = new Node(value); if (this.Head == null) { this.Head = tmpNode; } else { BinomialHeap tmpHeap = new BinomialHeap(); tmpHeap.Head = tmpNode; this.union(tmpHeap); } return(true); } return(false); }
public void deleteMinimum() { BinomialHeap resultHeap = new BinomialHeap(); Node minRoot = findMinimum(); removeFromRoots(minRoot); Node newRoot = minRoot.Child; removeFromChildren(minRoot); resultHeap.Head = newRoot; if (resultHeap.Head == null) { return; } newRoot = newRoot.Sibling; resultHeap.Head.Sibling = null; while (newRoot != null) { BinomialHeap tmp = new BinomialHeap(); tmp.Head = newRoot; newRoot = newRoot.Sibling; tmp.Head.Sibling = null; resultHeap.union(tmp); } if (this.Head == null) { this.Head = resultHeap.Head; } else { this.union(resultHeap); } }
static void TestCase2() { var random = new Random(); var myHeap = new BinomialHeap<double>(double.MinValue, Comparer<double>.Default); var otherQueue = new FastPriorityQueue<FastPriorityQueueNode>(10000); for (var i = 0; i < 10000; i++) { if (otherQueue.Any() && random.Next(3) == 0) { Assert(Math.Abs(myHeap.ExtractMin().Item2 - otherQueue.Dequeue().Priority) < double.Epsilon); } else { var newValue = random.NextDouble()*10; myHeap.Insert(newValue); otherQueue.Enqueue(new FastPriorityQueueNode(), newValue); } } while(otherQueue.Any()) Assert(Math.Abs(myHeap.ExtractMin().Item2 - otherQueue.Dequeue().Priority) < double.Epsilon); }
public bool readHeapFromFile(string path) { BinomialHeap heap = new BinomialHeap(); string[] lines; try { lines = File.ReadAllLines(path); string[] roots = lines[0].Split(';'); heap.insert(roots[0]); Node root = heap.Head; for (int i = 1; i < roots.Length; i++) { root.Sibling = new Node(roots[i]); root = root.Sibling; } for (int i = 1; i < lines.Length; i += 2) { string key = lines[i].TrimEnd('#'); Node parent = heap.findNodeByValue(key); string[] children = lines[i + 1].Split(';'); Node firstChild = new Node(children[0]); firstChild.Parent = parent; parent.Child = firstChild; parent.Degree = children.Length; Node sibling = parent.Child; for (int j = 1; j < children.Length; j++) { Node child = new Node(children[j]); child.Parent = parent; sibling.Sibling = child; sibling = sibling.Sibling; } } this.Head = heap.Head; Console.WriteLine("Plik został wczytany."); } catch (FileNotFoundException) { Console.WriteLine("\nPlik o podanej nazwie nie istnieje."); return(false); } catch (ArgumentException) { Console.WriteLine("\nŚcieżka nie może być pusta."); return(false); } catch (Exception e) { Console.WriteLine("Wystąpił błąd"); Console.WriteLine(e); } finally { Console.WriteLine("Naciśnij dowolny klawisz aby kontynuować..."); Console.ReadKey(); } return(true); }
static void Main(string[] args) { BinomialHeap heap = new BinomialHeap(); Node h = heap.Init(); h = heap.Insert(h, Node.Create(7)); h = heap.Insert(h, Node.Create(5)); h = heap.Insert(h, Node.Create(4)); h = heap.Insert(h, Node.Create(8)); h = heap.Insert(h, Node.Create(11)); h = heap.Insert(h, Node.Create(12)); h = heap.Insert(h, Node.Create(6)); h = heap.Insert(h, Node.Create(3)); heap.ExtractMinimum(h); heap.DecreaseKey(h, 5, 2); heap.Delete(h, 4); Console.WriteLine("Press any key..."); Console.ReadKey(); }