예제 #1
0
 /// <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));
 }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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;
            }
        }