A weighted search must always expand the cheapest frontier cell next, which needs a priority queue. Today you start building one by hand, a binary min-heap in a slice, and get its push and peek right.
Build a binary min-heap backed by a slice, with push and a peek at the minimum.
Dijkstra’s algorithm needs to repeatedly pull out the cheapest frontier cell, so
a plain queue will not do. The right tool is a priority queue, and the classic
implementation is a binary min-heap: a complete binary tree, flattened into a
slice, where every parent is no larger than its children. That invariant keeps the
smallest element sitting at index 0, ready to peek in constant time.
Pushing keeps the invariant with a sift up. Append the new item at the end, then
walk it toward the root, swapping with its parent ((i-1)/2) as long as it is
smaller. It stops as soon as it reaches a parent no larger than itself. We build this
ourselves rather than reach for a library so the ordering is fully in our hands,
which matters in two lessons when equal priorities need a deterministic tie-break.
Popping the minimum back out is next.
type Item struct { Priority int; Cell Coord } // Seq is added in a later lessontype Heap struct { items []Item }func (h *Heap) Peek() Item { return h.items[0] } // min is always at index 0func (h *Heap) Push(it Item) {h.items = append(h.items, it) // add at the endi := len(h.items) - 1for i > 0 { // sift up while smaller than parentp := (i - 1) / 2if h.items[i].Priority >= h.items[p].Priority { break }h.items[i], h.items[p] = h.items[p], h.items[i]i = p}}