-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathheap_sort.go
108 lines (93 loc) · 2.28 KB
/
heap_sort.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package heap
import "math"
type (
// Vertex is a node in a heap.
Vertex struct {
// Val is the value of the vertex.
Val int
// Left is the left child of the vertex.
Left *Vertex
// Right is the right child of the vertex.
Right *Vertex
}
// MinHeap is a heap where the root is always the minimum value.
MinHeap struct {
Data []*Vertex
}
)
// Sort solves the problem in O(n*Log n) time and O(n) space.
func Sort(list []int) []int {
sorted := []int{}
heap := NewMinHeap()
for _, val := range list {
heap.Push(val)
}
for heap.Len() > 0 {
sorted = append(sorted, heap.Pop())
}
return sorted
}
// NewMinHeap Returns a new Min Heap.
func NewMinHeap() *MinHeap {
return &MinHeap{
Data: []*Vertex{},
}
}
// Push inserts a new value into the heap.
func (m *MinHeap) Push(value int) {
vertex := &Vertex{
Val: value,
}
m.Data = append(m.Data, vertex)
m.percolateUp(len(m.Data) - 1)
}
// Pop removes the root value from the heap.
func (m *MinHeap) Pop() int {
if len(m.Data) == 0 {
return math.MinInt
}
rootValue := m.Data[0].Val
lastIndex := len(m.Data) - 1
m.Data[0] = m.Data[lastIndex]
m.Data = m.Data[:lastIndex]
m.percolateDown(0)
return rootValue
}
// Len returns the number of elements in the heap.
func (m *MinHeap) Len() int {
return len(m.Data)
}
// percolateUp swaps the vertex up the heap to maintain the heap property.
func (m *MinHeap) percolateUp(index int) {
for index > 0 {
parentIndex := (index - 1) / 2
if m.Data[parentIndex].Val <= m.Data[index].Val {
break
}
m.swap(parentIndex, index)
index = parentIndex
}
}
// percolateDown moves the vertex down the heap to maintain the heap property.
func (m *MinHeap) percolateDown(index int) {
for {
leftChildIndex := 2*index + 1
rightChildIndex := 2*index + 2
smallestIndex := index
if leftChildIndex < len(m.Data) && m.Data[leftChildIndex].Val < m.Data[smallestIndex].Val {
smallestIndex = leftChildIndex
}
if rightChildIndex < len(m.Data) && m.Data[rightChildIndex].Val < m.Data[smallestIndex].Val {
smallestIndex = rightChildIndex
}
if smallestIndex == index {
break
}
m.swap(index, smallestIndex)
index = smallestIndex
}
}
// swap swaps the positions of two vertices in the heap.
func (m *MinHeap) swap(i, j int) {
m.Data[i], m.Data[j] = m.Data[j], m.Data[i]
}