Beispiel #1
0
        public PriorityQueueNode <T> Enqueue(T item)
        {
            var result = new PriorityQueueNode <T>(item);

            Enqueue(result);
            return(result);
        }
Beispiel #2
0
        /// <summary>Add an element to the priority queue - O(log(n)) time operation.</summary>
        /// <param name="item">The item to be added to the queue</param>
        public void Enqueue([NotNull] PriorityQueueNode <T> item)
        {
            if (item.Index != -1)
            {
                throw new InvalidOperationException("Item belongs to another PriorityNodeQueue.");
            }

            // We add the item to the end of the list (at the bottom of the
            // tree). Then, the heap-property could be violated between this element
            // and it's parent. If this is the case, we swap this element with the
            // parent (a safe operation to do since the element is known to be less
            // than it's parent). Now the element move one level up the tree. We repeat
            // this test with the element and it's new parent. The element, if lesser
            // than everybody else in the tree will eventually bubble all the way up
            // to the root of the tree (or the head of the list). It is easy to see
            // this will take log(N) time, since we are working with a balanced binary
            // tree.
            var n = items.Count;

            items.Add(item);
            item.Index = n;
            while (n != 0)
            {
                var p = n / 2;    // This is the 'parent' of this item
                if (comparer.Compare(items[n].Value, items[p].Value) >= 0)
                {
                    break;  // Item >= parent
                }
                // Swap item and parent
                var tmp  = items[n];
                var tmp2 = items[p];
                tmp2.Index = n;
                tmp.Index  = p;
                items[n]   = tmp2;
                items[p]   = tmp;

                n = p;            // And continue
            }
        }
Beispiel #3
0
        /// <summary>
        /// Removes the specified item.
        /// </summary>
        /// <param name="item">The item to remove.</param>
        public void Remove([NotNull] PriorityQueueNode <T> item)
        {
            var index = item.Index;

            if (index == -1)
            {
                return;
            }

            // The element to return is of course the first element in the array,
            // or the root of the tree. However, this will leave a 'hole' there. We
            // fill up this hole with the last element from the array. This will
            // break the heap property. So we bubble the element downwards by swapping
            // it with it's lower child until it reaches it's correct level. The lower
            // child (one of the orignal elements with index 1 or 2) will now be at the
            // head of the queue (root of the tree).
            var nMax    = items.Count - 1;
            var itemMax = items[nMax];

            itemMax.Index = index;
            var itemToRemove = items[index];

            itemToRemove.Index = -1;
            items[index]       = itemMax;
            items.RemoveAt(nMax);  // Move the last element to the top

            var p = index;

            while (true)
            {
                // c is the child we want to swap with. If there
                // is no child at all, then the heap is balanced
                var c = p * 2; if (c >= nMax)
                {
                    break;
                }

                // If the second child is smaller than the first, that's the one
                // we want to swap with this parent.
                if (c + 1 < nMax && comparer.Compare(items[c + 1].Value, items[c].Value) < 0)
                {
                    c++;
                }
                // If the parent is already smaller than this smaller child, then
                // we are done
                if (comparer.Compare(items[p].Value, items[c].Value) <= 0)
                {
                    break;
                }

                // Othewise, swap parent and child, and follow down the parent
                var tmp  = items[p];
                var tmp2 = items[c];
                tmp.Index  = c;
                tmp2.Index = p;
                items[p]   = tmp2;
                items[c]   = tmp;
                p          = c;
            }

            item.Index = -1;
        }