public void removechild(HeapNode node) { if (node.parent != this) { throw new Exception("Cannot remove child from node that is not it's parent"); } if (node.issingle()) { if (child != node) { throw new Exception("Cannot remove node that is not a child"); } child = null; } else { if (child == node) { child = node.next; } node.remove(); } node.parent = null; node.mark = false; degree--; }
public void merge(FibHeap heap) { this.minnode.insert(heap.minnode); if (minnode == null || (heap.minnode != null && heap.minnode.key < minnode.key)) { minnode = heap.minnode; } count += heap.count; }
public void insert(HeapNode node) { if (node != null) { next.previous = node.previous; node.previous.next = next; next = node; node.previous = this; } }
public void addchild(HeapNode node) { if (child == null) { child = node; } else { child.insert(node); } node.parent = this; node.mark = false; degree++; }
public void _insertnode(HeapNode node) { if (minnode == null) { minnode = node; } else { minnode.insert(node); if (node.key < minnode.key) { minnode = node; } } }
public void decreasekey(HeapNode node, int newkey) { if (newkey > node.key) { throw new Exception("Cannot decrease key to a greater value"); } else if (newkey == node.key) { return; } node.key = newkey; HeapNode parent = node.parent; if (parent == null) { if (newkey < minnode.key) { minnode = node; } return; } else if (parent.key <= newkey) { return; } while (true) { parent.removechild(node); _insertnode(node); if (parent.parent == null) { break; } else if (parent.mark == false) { parent.mark = true; break; } else { node = parent; parent = parent.parent; continue; } } }
public void remove() { previous.next = next; next.previous = previous; next = previous = this; }
public HeapNode(int key, Node value) { this.key = key; this.value = value; previous = next = this; }
public void removeminimum() { if (minnode == null) { throw new Exception("Cannot remove from empty heap"); } count--; if (minnode.child != null) { HeapNode c = minnode.child; while (true) { c.parent = null; c = c.next; if (c == minnode.child) { break; } } minnode.child = null; minnode.insert(c); } if (minnode.next == minnode) { if (count != 0) { throw new Exception("Heap error: Expected 0 keys. Count is " + count); } minnode = null; return; } int logsize = 100; HeapNode[] degreeroots = new HeapNode[logsize]; maxdegree = 0; HeapNode currentpointer = minnode.next; while (true) { int currentdegree = currentpointer.degree; HeapNode current = currentpointer; currentpointer = currentpointer.next; while (degreeroots[currentdegree] != null) { HeapNode other = degreeroots[currentdegree]; if (current.key > other.key) { HeapNode temp = other; other = current; current = temp; } other.remove(); current.addchild(other); degreeroots[currentdegree] = null; currentdegree++; } degreeroots[currentdegree] = current; if (currentpointer == minnode) { break; } } minnode = null; int newmaxdegree = 0; for (int i = 0; i < logsize; i++) { if (degreeroots[i] != null) { degreeroots[i].next = degreeroots[i].previous = degreeroots[i]; this._insertnode(degreeroots[i]); if (i > newmaxdegree) { newmaxdegree = i; } } } maxdegree = newmaxdegree; }
public void insert(HeapNode node) { count++; this._insertnode(node); }
public void solve() { int total = width * height; Node[,] prev = new Node[width, height]; int infinity = int.MaxValue - 1; int[,] distances = new int[width, height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { distances[x, y] = infinity; } } FibHeap unvisited = new FibHeap(); HeapNode[,] nodeindex = new HeapNode[width, height]; distances[Start.X, Start.Y] = 0; HeapNode startnode = new HeapNode(0, Start); nodeindex[Start.X, Start.Y] = startnode; unvisited.insert(startnode); count = 0; while (unvisited.count > 0) { count++; HeapNode n = unvisited.minimum(); unvisited.removeminimum(); Node u = n.value; if (distances[u.X, u.Y] == infinity) { break; } if (u.X == End.X && u.Y == End.Y) { break; } foreach (Node v in u.neighbors) { if (v.X != 0) { if (!visited[v.X, v.Y]) { int d = MathExt.abs(v.X - u.X) + MathExt.abs(v.Y - u.Y); int newdistance = distances[u.X, u.Y] + d; int remaining = MathExt.abs(v.X - End.X) + MathExt.abs(v.Y - End.Y); if (newdistance < distances[v.X, v.Y]) { HeapNode vnode = nodeindex[v.X, v.Y]; if (vnode == null) { vnode = new HeapNode(newdistance + remaining, v); unvisited.insert(vnode); nodeindex[v.X, v.Y] = vnode; distances[v.X, v.Y] = newdistance; prev[v.X, v.Y] = u; } else { unvisited.decreasekey(vnode, newdistance + remaining); distances[v.X, v.Y] = newdistance; prev[v.X, v.Y] = u; } } } } } visited[u.X, u.Y] = true; } result = new List <Node>(); Node current = End; while (current.X != 0) { result.Insert(0, current); current = prev[current.X, current.Y]; } }