/// <summary> /// Returns the smaller of the two children of the given node, if it has any children. time: O(1) /// </summary> /// <returns>The parent node.</returns> /// <param name="node">Node.</param> private State MinChild(State node) { if (1 + node.queueIndex * 2 >= queue.Count) { //No children return(null); } State child1 = queue[node.queueIndex * 2 + 1]; if (node.queueIndex * 2 + 2 >= queue.Count) { return(child1); } State child2 = queue[node.queueIndex * 2 + 2]; if (child2.PrioritizeOver(child1)) { return(child2); } else { return(child1); } }
/// <summary> /// Bubbles up the given node. O(log|V|) /// </summary> /// <param name="node">Node to bubble up.</param> private void BubbleUp(State node) { if (node.queueIndex == 0) { return; } State parent = queue[(int)Math.Ceiling(node.queueIndex / (decimal)2.0) - 1]; int position = node.queueIndex; //Switch the node with its parent until its parent is smaller that it. //In the worst case, the node goes from the bottom to the top. //This is a binary heap, so there can be at most log|V| switches. time: O(log|V|) while (position != 0 && node.PrioritizeOver(parent)) { queue[position] = parent; int childPosition = position; position = parent.queueIndex; node.queueIndex = position; parent.queueIndex = childPosition; if (position == 0) { break; } parent = queue[(int)Math.Ceiling(position / (decimal)2.0) - 1]; } queue[position] = node; }
/// <summary> /// Finds and returns the node with the smallest distance value. time: O(|V|) /// </summary> /// <returns>The node with the smallest distance value </returns> public State DeleteMin() { // iterate over queue and find the point that is closest to the path so far. State closestNode = nodes[0]; int indexOfClosest = 0; //Go over every node in the list. time: O(|V|) for (int i = 1; i < nodes.Count; i++) { State node = nodes[i]; if (node.PrioritizeOver(closestNode)) { closestNode = node; indexOfClosest = i; } } nodes.RemoveAt(indexOfClosest); return(closestNode); }
/// <summary> /// Sifts down the given node. time: O(log|V|) /// </summary> /// <param name="node">Node to sift down.</param> private void SiftDown(State node) { State minChild = MinChild(node); int position = node.queueIndex; //Switch the node with its smallest child until its smallest child is bigger that it. //In the worst case, the node goes from the top to the bottom. //This is a binary heap, so there can be at most log|V| switches. time: O(log|V|) while (minChild != null && minChild.PrioritizeOver(node)) { queue[position] = minChild; int parentPosition = position; position = minChild.queueIndex; node.queueIndex = position; minChild.queueIndex = parentPosition; minChild = MinChild(node); } queue[position] = node; }