Exemplo n.º 1
0
        void bubbleUpMax(int i)
        {
            if (i > 0)
            {
                T max = heap[i].last, iv = max;
                PriorityQueueHandle maxhandle = heap[i].lasthandle;
                int p = (i + 1) / 2 - 1;

                while (i > 0)
                {
                    if (comparer.Compare(iv, max = heap[p = (i + 1) / 2 - 1].last) > 0)
                    {
                        updateLast(i, max, heap[p].lasthandle);
                        max = iv;
                        i   = p;
                    }
                    else
                    {
                        break;
                    }
                }

                updateLast(i, iv, maxhandle);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Replace an item with a handle in a priority queue with a new item.
        /// Typically used for changing the priority of some queued object.
        /// </summary>
        /// <param name="handle">The handle for the old item</param>
        /// <param name="item">The new item</param>
        /// <returns>The old item</returns>
        public T Replace(PriorityQueueHandle handle, T item)
        {
            int  cell;
            bool isfirst;

            checkHandle(handle, out cell, out isfirst);
            if (size == 0)
            {
                throw new InvalidOperationException("Heap is empty");
            }

            T retval;

            if (isfirst)
            {
                retval           = heap[cell].first;
                heap[cell].first = item;
                if (size == 1)
                {
                }
                else if (size == 2 * cell + 1) // cell == lastcell
                {
                    int p = (cell + 1) / 2 - 1;
                    if (comparer.Compare(item, heap[p].last) > 0)
                    {
                        PriorityQueueHandle thehandle = heap[cell].firsthandle;
                        updateFirst(cell, heap[p].last, heap[p].lasthandle);
                        updateLast(p, item, thehandle);
                        bubbleUpMax(p);
                    }
                    else
                    {
                        bubbleUpMin(cell);
                    }
                }
                else if (heapifyMin(cell))
                {
                    bubbleUpMax(cell);
                }
                else
                {
                    bubbleUpMin(cell);
                }
            }
            else
            {
                retval          = heap[cell].last;
                heap[cell].last = item;
                if (heapifyMax(cell))
                {
                    bubbleUpMin(cell);
                }
                else
                {
                    bubbleUpMax(cell);
                }
            }

            return(retval);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Check safely if a handle is valid for this queue and if so, report the corresponding queue item.
        /// </summary>
        /// <param name="handle">The handle to check</param>
        /// <param name="item">If the handle is valid this will contain the corresponding item on output.</param>
        /// <returns>True if the handle is valid.</returns>
        public bool Find(PriorityQueueHandle handle, out T item)
        {
            PriorityQueueHandle myhandle = handle;

            if (myhandle == null)
            {
                item = default(T);
                return(false);
            }
            int  toremove = myhandle.index;
            int  cell     = toremove / 2;
            bool isfirst  = toremove % 2 == 0;

            {
                if (toremove == -1 || toremove >= size)
                {
                    item = default(T);
                    return(false);
                }
                PriorityQueueHandle actualhandle = isfirst ? heap[cell].firsthandle : heap[cell].lasthandle;
                if (actualhandle != myhandle)
                {
                    item = default(T);
                    return(false);
                }
            }
            item = isfirst ? heap[cell].first : heap[cell].last;
            return(true);
        }
Exemplo n.º 4
0
        void bubbleUpMin(int i)
        {
            if (i > 0)
            {
                T min = heap[i].first, iv = min;
                PriorityQueueHandle minhandle = heap[i].firsthandle;
                int p = (i + 1) / 2 - 1;

                while (i > 0)
                {
                    if (comparer.Compare(iv, min = heap[p = (i + 1) / 2 - 1].first) < 0)
                    {
                        updateFirst(i, min, heap[p].firsthandle);
                        min = iv;
                        i   = p;
                    }
                    else
                    {
                        break;
                    }
                }

                updateFirst(i, iv, minhandle);
            }
        }
Exemplo n.º 5
0
        private bool add(PriorityQueueHandle itemhandle, T item)
        {
            if (size == 0)
            {
                size = 1;
                updateFirst(0, item, itemhandle);
                return(true);
            }

            if (size == 2 * heap.Length)
            {
                Interval[] newheap = new Interval[2 * heap.Length];

                Array.Copy(heap, newheap, heap.Length);
                heap = newheap;
            }

            if (size % 2 == 0)
            {
                int i = size / 2, p = (i + 1) / 2 - 1;
                T   tmp = heap[p].last;

                if (comparer.Compare(item, tmp) > 0)
                {
                    updateFirst(i, tmp, heap[p].lasthandle);
                    updateLast(p, item, itemhandle);
                    bubbleUpMax(p);
                }
                else
                {
                    updateFirst(i, item, itemhandle);

                    if (comparer.Compare(item, heap[p].first) < 0)
                    {
                        bubbleUpMin(i);
                    }
                }
            }
            else
            {
                int i     = size / 2;
                T   other = heap[i].first;

                if (comparer.Compare(item, other) < 0)
                {
                    updateLast(i, other, heap[i].firsthandle);
                    updateFirst(i, item, itemhandle);
                    bubbleUpMin(i);
                }
                else
                {
                    updateLast(i, item, itemhandle);
                    bubbleUpMax(i);
                }
            }
            size++;

            return(true);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Find the current least item of this priority queue.
 /// </summary>
 /// <param name="handle">On return: the handle of the item.</param>
 /// <returns>The least item.</returns>
 public T FindMin(out PriorityQueueHandle handle)
 {
     if (size == 0)
     {
         throw new InvalidOperationException("Heap is empty");
     }
     handle = heap[0].firsthandle;
     return(heap[0].first);
 }
Exemplo n.º 7
0
 private void updateFirst(int cell, T item, PriorityQueueHandle handle)
 {
     heap[cell].first = item;
     if (handle != null)
     {
         handle.index = 2 * cell;
     }
     heap[cell].firsthandle = handle;
 }
Exemplo n.º 8
0
        /// <summary>
        /// Remove the largest item from this priority queue.
        /// </summary>
        /// <param name="handle">On return: the handle of the removed item.</param>
        /// <returns>The removed item.</returns>
        public T DeleteMax(out PriorityQueueHandle handle)
        {
            if (size == 0)
            {
                throw new InvalidOperationException("Heap is empty");
            }

            T retval;
            PriorityQueueHandle myhandle;

            if (size == 1)
            {
                size     = 0;
                retval   = heap[0].first;
                myhandle = heap[0].firsthandle;
                if (myhandle != null)
                {
                    myhandle.index = -1;
                }
                heap[0].first       = default(T);
                heap[0].firsthandle = null;
            }
            else
            {
                retval   = heap[0].last;
                myhandle = heap[0].lasthandle;
                if (myhandle != null)
                {
                    myhandle.index = -1;
                }

                int lastcell = (size - 1) / 2;

                if (size % 2 == 0)
                {
                    updateLast(0, heap[lastcell].last, heap[lastcell].lasthandle);
                    heap[lastcell].last       = default(T);
                    heap[lastcell].lasthandle = null;
                }
                else
                {
                    updateLast(0, heap[lastcell].first, heap[lastcell].firsthandle);
                    heap[lastcell].first       = default(T);
                    heap[lastcell].firsthandle = null;
                }

                size--;
                heapifyMax(0);
            }

            handle = myhandle;
            return(retval);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Get or set the item corresponding to a handle.
        /// </summary>
        /// <param name="handle">The reference into the heap</param>
        /// <returns></returns>
        public T this[PriorityQueueHandle handle]
        {
            get
            {
                int  cell;
                bool isfirst;
                checkHandle(handle, out cell, out isfirst);

                return(isfirst ? heap[cell].first : heap[cell].last);
            }
            set
            {
                Replace(handle, value);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Add an item to the priority queue, receiving a
        /// handle for the item in the queue,
        /// or reusing an already existing handle.
        /// </summary>
        /// <param name="handle">On output: a handle for the added item.
        /// On input: null for allocating a new handle, an invalid handle for reuse.
        /// A handle for reuse must be compatible with this priority queue,
        /// by being created by a priority queue of the same runtime type, but not
        /// necessarily the same priority queue object.</param>
        /// <param name="item">The item to add.</param>
        /// <returns>True since item will always be added unless the call throws an exception.</returns>
        public bool Add(ref PriorityQueueHandle handle, T item)
        {
            PriorityQueueHandle myhandle = handle;

            if (myhandle == null)
            {
                handle = myhandle = new PriorityQueueHandle();
            }
            else
            if (myhandle.index != -1)
            {
                throw new ArgumentException("Handle not valid for reuse");
            }
            if (add(myhandle, item))
            {
                return(true);
            }
            return(false);
        }
Exemplo n.º 11
0
        private PriorityQueueHandle checkHandle(PriorityQueueHandle handle, out int cell, out bool isfirst)
        {
            PriorityQueueHandle myhandle = handle;
            int toremove = myhandle.index;

            cell    = toremove / 2;
            isfirst = toremove % 2 == 0;
            {
                if (toremove == -1 || toremove >= size)
                {
                    throw new ArgumentException("Invalid handle, index out of range");
                }
                PriorityQueueHandle actualhandle = isfirst ? heap[cell].firsthandle : heap[cell].lasthandle;
                if (actualhandle != myhandle)
                {
                    throw new ArgumentException("Invalid handle, doesn't match queue");
                }
            }
            return(myhandle);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Delete an item with a handle from a priority queue.
        /// </summary>
        /// <param name="handle">The handle for the item. The handle will be invalidated, but reusable.</param>
        /// <returns>The deleted item</returns>
        public T Delete(PriorityQueueHandle handle)
        {
            int  cell;
            bool isfirst;
            PriorityQueueHandle myhandle = checkHandle(handle, out cell, out isfirst);

            T retval;

            myhandle.index = -1;
            int lastcell = (size - 1) / 2;

            if (cell == lastcell)
            {
                if (isfirst)
                {
                    retval = heap[cell].first;
                    if (size % 2 == 0)
                    {
                        updateFirst(cell, heap[cell].last, heap[cell].lasthandle);
                        heap[cell].last       = default(T);
                        heap[cell].lasthandle = null;
                    }
                    else
                    {
                        heap[cell].first       = default(T);
                        heap[cell].firsthandle = null;
                    }
                }
                else
                {
                    retval                = heap[cell].last;
                    heap[cell].last       = default(T);
                    heap[cell].lasthandle = null;
                }
                size--;
            }
            else if (isfirst)
            {
                retval = heap[cell].first;

                if (size % 2 == 0)
                {
                    updateFirst(cell, heap[lastcell].last, heap[lastcell].lasthandle);
                    heap[lastcell].last       = default(T);
                    heap[lastcell].lasthandle = null;
                }
                else
                {
                    updateFirst(cell, heap[lastcell].first, heap[lastcell].firsthandle);
                    heap[lastcell].first       = default(T);
                    heap[lastcell].firsthandle = null;
                }

                size--;
                if (heapifyMin(cell))
                {
                    bubbleUpMax(cell);
                }
                else
                {
                    bubbleUpMin(cell);
                }
            }
            else
            {
                retval = heap[cell].last;

                if (size % 2 == 0)
                {
                    updateLast(cell, heap[lastcell].last, heap[lastcell].lasthandle);
                    heap[lastcell].last       = default(T);
                    heap[lastcell].lasthandle = null;
                }
                else
                {
                    updateLast(cell, heap[lastcell].first, heap[lastcell].firsthandle);
                    heap[lastcell].first       = default(T);
                    heap[lastcell].firsthandle = null;
                }

                size--;
                if (heapifyMax(cell))
                {
                    bubbleUpMin(cell);
                }
                else
                {
                    bubbleUpMax(cell);
                }
            }

            return(retval);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Remove the largest item from this  priority queue.
        /// </summary>
        /// <returns>The removed item.</returns>
        public T DeleteMax()
        {
            PriorityQueueHandle handle = null;

            return(DeleteMax(out handle));
        }
Exemplo n.º 14
0
        bool heapifyMax(int i)
        {
            bool swappedroot = false;
            int  cell = i, currentmax = cell;
            T    currentitem = heap[cell].last;
            PriorityQueueHandle currenthandle = heap[cell].lasthandle;

            if (i > 0)
            {
                T other = heap[cell].first;
                if (comparer.Compare(currentitem, other) < 0)
                {
                    swappedroot = true;
                    PriorityQueueHandle otherhandle = heap[cell].firsthandle;
                    updateFirst(cell, currentitem, currenthandle);
                    currentitem   = other;
                    currenthandle = otherhandle;
                }
            }

            T maxitem = currentitem;
            PriorityQueueHandle maxhandle = currenthandle;

            while (true)
            {
                int l = 2 * cell + 1, r = l + 1;
                T   lv, rv;

                if (2 * l + 1 < size && comparer.Compare(lv = heap[l].last, maxitem) > 0)
                {
                    currentmax = l; maxitem = lv;
                }

                if (2 * r + 1 < size && comparer.Compare(rv = heap[r].last, maxitem) > 0)
                {
                    currentmax = r; maxitem = rv;
                }

                if (currentmax == cell)
                {
                    break;
                }

                maxhandle = heap[currentmax].lasthandle;
                updateLast(cell, maxitem, maxhandle);
                cell = currentmax;

                //Maybe swap first and last
                T other = heap[cell].first;
                if (comparer.Compare(currentitem, other) < 0)
                {
                    PriorityQueueHandle otherhandle = heap[cell].firsthandle;
                    updateFirst(cell, currentitem, currenthandle);
                    currentitem   = other;
                    currenthandle = otherhandle;
                }

                maxitem   = currentitem;
                maxhandle = currenthandle;
            }

            if (cell != i || swappedroot) //Check could be better?
            {
                updateLast(cell, maxitem, maxhandle);
            }
            return(swappedroot);
        }
Exemplo n.º 15
0
        bool heapifyMin(int i)
        {
            bool swappedroot = false;
            int  cell = i, currentmin = cell;
            T    currentitem = heap[cell].first;
            PriorityQueueHandle currenthandle = heap[cell].firsthandle;

            if (i > 0)
            {
                T other = heap[cell].last;
                if (2 * cell + 1 < size && comparer.Compare(currentitem, other) > 0)
                {
                    swappedroot = true;
                    PriorityQueueHandle otherhandle = heap[cell].lasthandle;
                    updateLast(cell, currentitem, currenthandle);
                    currentitem   = other;
                    currenthandle = otherhandle;
                }
            }

            T minitem = currentitem;
            PriorityQueueHandle minhandle = currenthandle;

            while (true)
            {
                int l = 2 * cell + 1, r = l + 1;
                T   lv, rv;

                if (2 * l < size && comparer.Compare(lv = heap[l].first, minitem) < 0)
                {
                    currentmin = l; minitem = lv;
                }

                if (2 * r < size && comparer.Compare(rv = heap[r].first, minitem) < 0)
                {
                    currentmin = r; minitem = rv;
                }

                if (currentmin == cell)
                {
                    break;
                }

                minhandle = heap[currentmin].firsthandle;
                updateFirst(cell, minitem, minhandle);
                cell = currentmin;

                //Maybe swap first and last
                T other = heap[cell].last;
                if (2 * currentmin + 1 < size && comparer.Compare(currentitem, other) > 0)
                {
                    PriorityQueueHandle otherhandle = heap[cell].lasthandle;
                    updateLast(cell, currentitem, currenthandle);
                    currentitem   = other;
                    currenthandle = otherhandle;
                }


                minitem   = currentitem;
                minhandle = currenthandle;
            }

            if (cell != i || swappedroot)
            {
                updateFirst(cell, minitem, minhandle);
            }
            return(swappedroot);
        }