/// <summary> /// Merges two priority queues /// </summary> /// <param name="pq1">first priority queue</param> /// <param name="pq2">second priority queue</param> /// <returns>resultant priority queue</returns> /// <remarks> /// source priority queues must have equal comparers, /// otherwise <see cref="InvalidOperationException"/> will be thrown /// </remarks> public static MaxPriorityQueue <TPriority, TValue> MergeQueues(MaxPriorityQueue <TPriority, TValue> pq1, MaxPriorityQueue <TPriority, TValue> pq2) { if (pq1 == null || pq2 == null) { throw new ArgumentNullException(); } if (pq1._comparer != pq2._comparer) { throw new InvalidOperationException("Priority queues to be merged must have equal comparers"); } return(MergeQueues(pq1, pq2, pq1._comparer)); }
/// <summary> /// Merges two priority queues and sets specified comparer for resultant priority queue /// </summary> /// <param name="pq1">first priority queue</param> /// <param name="pq2">second priority queue</param> /// <param name="comparer">comparer for resultant priority queue</param> /// <returns>resultant priority queue</returns> public static MaxPriorityQueue <TPriority, TValue> MergeQueues(MaxPriorityQueue <TPriority, TValue> pq1, MaxPriorityQueue <TPriority, TValue> pq2, IComparer <TPriority> comparer) { if (pq1 == null || pq2 == null || comparer == null) { throw new ArgumentNullException(); } // merge data MaxPriorityQueue <TPriority, TValue> result = new MaxPriorityQueue <TPriority, TValue>(pq1.Count + pq2.Count, pq1._comparer); result._baseHeap.AddRange(pq1._baseHeap); result._baseHeap.AddRange(pq2._baseHeap); // heapify data for (int pos = result._baseHeap.Count / 2 - 1; pos >= 0; pos--) { result.HeapifyFromBeginningToEnd(pos); } return(result); }
public static void Execute(string inputFile) { MaxPriorityQueue <int, int> hLow = new MaxPriorityQueue <int, int>(); PriorityQueue <int, int> hHigh = new PriorityQueue <int, int>(); string[] lines = File.ReadAllLines(inputFile); int medianSum = 0; //hHigh.Enqueue(1, 0); //hHigh.Enqueue(2, 0); //hHigh.Enqueue(3, 0); //hHigh.Enqueue(4, 0); //hLow.Enqueue(1, 0); //hLow.Enqueue(2, 0); //hLow.Enqueue(3, 0); //hLow.Enqueue(4, 0); // Maintain invariant ~ i/2 smallest(or largest) elements in hLow(or hHigh) /* If incoming i > hLow, enqueue in hHigh and vice-versa. * if count(hLow) > count(hHigh), Dequeue hLow to hHigh and vice-versa. */ foreach (string line in lines) { int x = Int32.Parse(line); // If hLow is empty, enqueue x if (hLow.Count == 0) { hLow.Enqueue(x, 0); medianSum += hLow.Peek().Key; continue; } if (x > hLow.Peek().Key) { hHigh.Enqueue(x, 0); } else { hLow.Enqueue(x, 0); } // Balance heaps if (hLow.Count > hHigh.Count) { if (hLow.Count - hHigh.Count > 1) { hHigh.Enqueue(hLow.Dequeue().Key, 0); } } else { if (hHigh.Count - hLow.Count > 1) { hLow.Enqueue(hHigh.Dequeue().Key, 0); } } medianSum += ((hLow.Count + hHigh.Count) % 2 == 0) ? hLow.Peek().Key : (hLow.Count > hHigh.Count) ? hLow.Peek().Key : hHigh.Peek().Key; } }