示例#1
0
        /// <summary>
        ///   Removes a node from the queue. The node does not need to be the head of the
        ///   queue. This is an O(log n) operation.
        /// </summary>
        ///
        public void Remove(PriorityQueueNode <T> node)
        {
#if DEBUG
            if (!Contains(node))
            {
                throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + node);
            }
#endif
            CheckQueue();

            // If the node is already the last node, we can remove it immediately
            if (node.QueueIndex == numberOfNodes)
            {
                nodes[numberOfNodes] = PriorityQueueNode <T> .Empty;
                numberOfNodes--;
                return;
            }

            int index = node.QueueIndex;
            // Swap the node with the last node
            swap(node.QueueIndex, numberOfNodes);
            nodes[numberOfNodes] = PriorityQueueNode <T> .Empty;
            numberOfNodes--;

            // Now bubble formerLastNode (which is no longer the last node) up or down as appropriate
            OnNodeUpdated(ref nodes[index]);

            CheckQueue();
        }
示例#2
0
        /// <summary>
        /// Compares the current object with another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other" /> parameter.Zero This object is equal to <paramref name="other" />. Greater than zero This object is greater than <paramref name="other" />.
        /// </returns>
        public int CompareTo(PriorityQueueNode <T> other)
        {
            int order = this.Priority.CompareTo(other.Priority);

            if (order == 0)
            {
                order = this.InsertionIndex.CompareTo(other.InsertionIndex);
            }
            return(order);
        }
示例#3
0
        public bool Contains(PriorityQueueNode <T> node)
        {
#if DEBUG
            if (node.QueueIndex < 0 || node.QueueIndex >= nodes.Length)
            {
                throw new InvalidOperationException("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?");
            }
#endif
            return(nodes[node.QueueIndex] == node);
        }
示例#4
0
        public void UpdatePriority(ref PriorityQueueNode <T> node, double priority)
        {
#if DEBUG
            if (!Contains(node))
            {
                throw new InvalidOperationException("Cannot call UpdatePriority() on a node which is not enqueued: " + node);
            }
#endif
            node.Priority = priority;
            OnNodeUpdated(ref node);
        }
示例#5
0
        /// <summary>
        ///   Returns an array containing the items in this list,
        ///   optionally in in priority order.
        /// </summary>
        ///
        /// <param name="sorted">Whether to return the items in priority order.</param>
        ///
        public PriorityQueueNode <T>[] ToArray(bool sorted = true)
        {
            var result = new PriorityQueueNode <T> [numberOfNodes];

            for (int i = 0; i < result.Length; i++)
            {
                result[i] = nodes[i + 1];
            }
            if (sorted)
            {
                Array.Sort(result);
            }
            return(result);
        }
示例#6
0
        private void OnNodeUpdated(ref PriorityQueueNode <T> node)
        {
            // Bubble the updated node up or down as appropriate
            int parentIndex = node.QueueIndex / 2;

            if (parentIndex > 0 && HasHigherPriority(node.QueueIndex, parentIndex))
            {
                cascadeUp(ref node);
            }
            else
            {
                cascadeDown(ref node);
            }
        }
示例#7
0
        public PriorityQueueNode <T> Enqueue(T value, double priority)
        {
            CheckQueue();

            numberOfNodes++;
            if (numberOfNodes >= nodes.Length)
            {
                Resize(nodes.Length + (int)(0.1 * nodes.Length));
            }

            var node = new PriorityQueueNode <T>(value, priority, numberOfNodes, counter++);

            nodes[numberOfNodes] = node;
            cascadeUp(ref nodes[numberOfNodes]);

            CheckQueue();
            return(node);
        }
示例#8
0
        private void cascadeDown(ref PriorityQueueNode <T> node)
        {
            // aka Heapify-down
            int newParent;
            int finalQueueIndex = node.QueueIndex;

            while (true)
            {
                newParent = nodes[finalQueueIndex].QueueIndex;
                int childLeftIndex = 2 * finalQueueIndex;

                // Check if the left-child is higher-priority than the current node
                if (childLeftIndex > numberOfNodes)
                {
                    break;
                }

                if (HasHigherPriority(childLeftIndex, newParent))
                {
                    newParent = childLeftIndex;
                }

                // Check if the right-child is higher-priority than either the current node or the left child
                int childRightIndex = childLeftIndex + 1;
                if (childRightIndex <= numberOfNodes)
                {
                    if (HasHigherPriority(childRightIndex, newParent))
                    {
                        newParent = childRightIndex;
                    }
                }

                // If either of the children has higher (smaller) priority, swap and continue cascading
                if (newParent != finalQueueIndex)
                {
                    swap(finalQueueIndex, newParent);
                    finalQueueIndex = newParent;
                }
                else
                {
                    break;
                }
            }
        }
示例#9
0
        private void cascadeUp(ref PriorityQueueNode <T> node)
        {
            // aka Heapify-up
            int current = node.QueueIndex;
            int parent  = node.QueueIndex / 2;

            while (parent >= 1)
            {
                if (HasHigherPriority(parent, current))
                {
                    break;
                }

                // Node has lower priority value, so move it up the heap
                swap(current, parent);
                current = nodes[parent].QueueIndex;
                parent  = current / 2;
            }
        }
示例#10
0
        /// <summary>
        ///   Resize the queue so it can accept more nodes.  All currently enqueued nodes are kept.
        ///   Attempting to decrease the queue size to a size too small to hold the existing nodes
        ///   results in undefined behavior. This is an O(n) operation.
        /// </summary>
        ///
        public void Resize(int capacity)
        {
#if DEBUG
            if (capacity <= 0)
            {
                throw new InvalidOperationException("Queue size cannot be smaller than 1");
            }

            if (capacity < numberOfNodes)
            {
                throw new InvalidOperationException("Called Resize(" + capacity + "), but current queue contains " + numberOfNodes + " nodes");
            }
#endif

            var newArray           = new PriorityQueueNode <T> [capacity + 1];
            int highestIndexToCopy = Math.Min(capacity, numberOfNodes);
            for (int i = 1; i <= highestIndexToCopy; i++)
            {
                newArray[i] = nodes[i];
            }

            nodes = newArray;
        }
示例#11
0
 /// <summary>
 /// Indicates whether the current object is equal to another object of the same type.
 /// </summary>
 /// <param name="other">An object to compare with this object.</param>
 /// <returns>
 /// true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
 /// </returns>
 public bool Equals(PriorityQueueNode <T> other)
 {
     return(Value.Equals(other.value));
 }