/// <summary> /// Removes the given node from this queue if it is present. /// </summary> /// <param name="node"> /// The node to remove if present. /// </param> /// <returns> /// A value indicating whether the node was removed. /// </returns> public bool Remove(PriorityQueueNode <TPriority, TData> node) { if (!this.Contains(node)) { return(false); } if (this.Count <= 1) { this.nodes[1] = null; this.Count = 0; return(true); } bool wasSwapped = false; var formerLastNode = this.nodes[this.Count]; if (node.QueueIndex != this.Count) { this.Swap(node, formerLastNode); wasSwapped = true; } --this.Count; this.nodes[node.QueueIndex] = null; if (wasSwapped) { this.OnNodeUpdated(formerLastNode); } return(true); }
private void Swap(PriorityQueueNode <TPriority, TData> node1, PriorityQueueNode <TPriority, TData> node2) { this.nodes[node1.QueueIndex] = node2; this.nodes[node2.QueueIndex] = node1; int temp = node1.QueueIndex; node1.QueueIndex = node2.QueueIndex; node2.QueueIndex = temp; }
/// <summary> /// Changes the priority of the given node. /// </summary> /// <param name="node"> /// The node whose priority to change. /// </param> /// <param name="priority"> /// The new priority for the node. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="node"/> is <see langword="null"/>. /// </exception> public void ChangePriority(PriorityQueueNode <TPriority, TData> node, TPriority priority) { if (node == null) { throw new ArgumentNullException("node"); } node.Priority = priority; this.OnNodeUpdated(node); }
private void OnNodeUpdated(PriorityQueueNode <TPriority, TData> node) { int parentIndex = node.QueueIndex / 2; var parentNode = this.nodes[parentIndex]; if (parentIndex > 0 && this.HasHigherPriority(node, parentNode)) { this.HeapifyUp(node); } else { this.HeapifyDown(node); } }
private void HeapifyDown(PriorityQueueNode <TPriority, TData> node) { int finalQueueIndex = node.QueueIndex; while (true) { var newParent = node; int childLeftIndex = 2 * finalQueueIndex; if (childLeftIndex > this.Count) { node.QueueIndex = finalQueueIndex; this.nodes[finalQueueIndex] = node; break; } var childLeft = this.nodes[childLeftIndex]; if (this.HasHigherPriority(childLeft, newParent)) { newParent = childLeft; } int childRightIndex = childLeftIndex + 1; if (childRightIndex <= this.Count) { var childRight = this.nodes[childRightIndex]; if (this.HasHigherPriority(childRight, newParent)) { newParent = childRight; } } if (newParent != node) { this.nodes[finalQueueIndex] = newParent; int temp = newParent.QueueIndex; newParent.QueueIndex = finalQueueIndex; finalQueueIndex = temp; } else { node.QueueIndex = finalQueueIndex; this.nodes[finalQueueIndex] = node; break; } } }
private void HeapifyUp(PriorityQueueNode <TPriority, TData> node) { int parent = node.QueueIndex / 2; while (parent >= 1) { var parentNode = this.nodes[parent]; if (this.HasHigherPriority(parentNode, node)) { break; } this.Swap(node, parentNode); parent = node.QueueIndex / 2; } }
/// <summary> /// Adds a given node to the queue with the given priority. /// </summary> /// <param name="node"> /// The node to add to the queue. /// </param> /// <param name="priority"> /// The priority for the node. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="node"/> is <see langword="null"/>. /// </exception> public void Enqueue(PriorityQueueNode <TPriority, TData> node, TPriority priority) { if (node == null) { throw new ArgumentNullException("node"); } node.Priority = priority; node.QueueIndex = ++this.Count; if (this.nodes.Count <= this.Count) { this.nodes.Add(null); } this.nodes[this.Count] = node; this.HeapifyUp(this.nodes[this.Count]); }
/// <summary>Insert into the priority queue. Duplicates are allowed. /// </summary> /// <param name="x">The item to insert.</param> public void Add(T x) { var node = new PriorityQueueNode <T, T>(x); this._queue.Enqueue(node, x); }
private bool HasHigherPriority(PriorityQueueNode <TPriority, TData> higher, PriorityQueueNode <TPriority, TData> lower) { // The "higher-priority" item is actually the item whose priority // compares *lower*, because this is a min-heap. return(this.priorityComparer.Compare(higher.Priority, lower.Priority) < 0); }
/// <summary> /// Determines whether the given node is contained within this queue. /// </summary> /// <param name="node"> /// The node to locate in the queue. /// </param> /// <returns> /// <see langword="true"/> if <paramref name="node"/> is found in the /// queue, otherwise <see langword="false"/>. /// </returns> public bool Contains(PriorityQueueNode <TPriority, TData> node) { return(node != null && node.QueueIndex < this.nodes.Count && this.nodes[node.QueueIndex] == node); }