-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaxint.go
86 lines (79 loc) · 2.04 KB
/
maxint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package heaputil
/* For a given index into a slice or array acting as a binary heap,
calculate the index of the parent node. We are guaranteed of not
being presented an index less than 3. */
func getParentIndex(cIdx int) int {
var pIdx int
if cIdx%2 == 1 {
pIdx = (cIdx - 1) / 2
} else {
pIdx = (cIdx - 2) / 2
}
return pIdx
}
func siftDown(h []int, parent int) {
sliceLen := len(h)
leftChild := (2 * parent) + 1
for sliceLen > leftChild {
rightChild := leftChild + 1
swap := parent
if h[swap] < h[leftChild] {
swap = leftChild
}
if (rightChild < sliceLen) && (h[swap] < h[rightChild]) {
swap = rightChild
}
if swap == parent {
break
} else {
h[parent], h[swap] = h[swap], h[parent]
parent = swap
leftChild = (2 * parent) + 1
}
}
}
//MaxIntHeapify - take a slice of integers and turn it into a max heap
func MaxIntHeapify(h []int) {
sliceLen := len(h)
if sliceLen < 2 {
// Either empty or a single element, this is a valid "heap"
return
}
if sliceLen == 2 {
if h[0] < h[1] {
h[0], h[1] = h[1], h[0]
}
return
}
lastIndex := sliceLen - 1
for idx := getParentIndex(lastIndex); -1 < idx; idx-- {
siftDown(h, idx)
}
}
//MaxIntHeapPush - add a value to a MaxIntHeap. The returned slice will be a
//heap regardless of whether the initial parameter slice was one at the start.
func MaxIntHeapPush(s []int, v int) []int {
h := append(s, v)
MaxIntHeapify(h)
return h
}
//MaxIntHeapPop - take the max value from the heap and re-heapify. If the
//initial slice isn't a heap to start, you will get garbage out.
func MaxIntHeapPop(s []int) (int, []int) {
cpy := make([]int, len(s), cap(s))
copy(cpy, s)
maxVal := cpy[0]
lastIndex := len(cpy) - 1
cpy[0] = cpy[lastIndex]
cpy = cpy[:lastIndex]
MaxIntHeapify(cpy)
return maxVal, cpy
}
//MaxIntHeapSort - take a slice of integers and sort it in place, max value last
func MaxIntHeapSort(s []int) {
MaxIntHeapify(s) // just in case it's not a heap when we get it.
for idx := len(s) - 1; idx > 0; idx-- {
s[0], s[idx] = s[idx], s[0]
MaxIntHeapify(s[:idx])
}
}