Beispiel #1
0
// Removes and returns the minimum element of h.
func PopMin(h heap.Interface) interface{} {
	n := h.Len() - 1
	h.Swap(0, n)
	x := h.Pop()
	siftDownMin(h, 0, n)
	return x
}
Beispiel #2
0
func siftDownMin(h heap.Interface, i, n int) {
	for (i*2+2)*2+2 < n { // has four grandchildren
		m := minGrandchild(h, i, n)
		if h.Less(i, m) {
			return
		}
		h.Swap(i, m)
		if h.Less(parent(m), m) {
			h.Swap(m, parent(m))
		}
		i = m
	}

	if hasChild(i, n) {
		m := minTwoGen(h, i, n)
		if m > i*2+2 { // must be a grandchild
			if h.Less(m, i) {
				h.Swap(i, m)
				if h.Less(parent(m), m) {
					h.Swap(m, parent(m))
				}
				siftDownMin(h, m, n)
			}
		} else if h.Less(m, i) {
			h.Swap(i, m)
		}
	}
}
Beispiel #3
0
// Iterative version after Bojesen, "Heap implementations and variations",
// http://www.diku.dk/forskning/performance-engineering/Jesper/heaplab/heapsurvey_html/node11.html
func siftDownMax(h heap.Interface, i, n int) {
	for (i*2+2)*2+2 < n { // has four grandchildren
		m := maxGrandchild(h, i, n)
		if h.Less(m, i) {
			return
		}
		h.Swap(i, m)
		if h.Less(m, parent(m)) {
			h.Swap(m, parent(m))
		}
		i = m
	}

	// XXX Following is from the original paper; couldn't get Bojesen's version
	// to work.
	if hasChild(i, n) {
		m := maxTwoGen(h, i, n)
		if m > i*2+2 { // must be a grandchild
			if h.Less(i, m) {
				h.Swap(i, m)
				if h.Less(m, parent(m)) {
					h.Swap(m, parent(m))
				}
				siftDownMax(h, m, n)
			}
		} else if h.Less(i, m) {
			h.Swap(i, m)
		}
	}
}
Beispiel #4
0
func siftUpMin(h heap.Interface, i int) {
	for gp := parent(parent(i)); gp >= 0; i, gp = gp, parent(parent(gp)) {
		if h.Less(gp, i) {
			break
		}
		h.Swap(i, gp)
	}
}
Beispiel #5
0
// Removes and returns the maximum element of h.
func PopMax(h heap.Interface) interface{} {
	n := h.Len()
	if n <= 2 {
		return h.Pop()
	}

	i := 1
	if h.Less(1, 2) {
		i = 2
	}
	h.Swap(i, n-1)
	x := h.Pop()
	siftDownMax(h, i, n-1)
	return x
}
Beispiel #6
0
func siftUp(h heap.Interface, i int) {
	if minLevel(i) {
		if i > 0 && h.Less(parent(i), i) {
			h.Swap(i, parent(i))
			siftUpMax(h, parent(i))
		} else {
			siftUpMin(h, i)
		}
	} else {
		if i > 0 && h.Less(i, parent(i)) {
			h.Swap(i, parent(i))
			siftUpMin(h, parent(i))
		} else {
			siftUpMax(h, i)
		}
	}
}