-
Notifications
You must be signed in to change notification settings - Fork 0
/
MinHeap.java
120 lines (101 loc) · 3 KB
/
MinHeap.java
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
109
110
111
112
113
114
115
116
117
118
119
120
public class MinHeap {
private final Building[] heap;
private int size = 0;
public MinHeap(int size) {
heap = new Building[size];
}
// insert building to heap
public void add(Building value) {
if (isFull()) throw new IllegalStateException();
heap[size] = new Building(value);
size += 1;
heapifyUp(); // call heapify up to maintain min heap invariant
}
// remove the min element from heap
public Building remove() {
Building result = peek();
// replace the root with the last entry
heap[0] = new Building(heap[size - 1]);
heap[size - 1] = null;
size -= 1;
heapifyDown(); // call heapify down to maintain min heap invariant
return result;
}
// get min element from heap
public Building peek() {
if (this.isEmpty()) {
return null;
}
return heap[0];
}
// percolate downwards from root until heap invariant is maintained
public void heapifyDown() {
int index = 0;
while (hasLeftChild(index)) {
int leftChild = leftIndex(index);
int smallerChild = leftChild;
if (hasRightChild(index)) {
int rightChild = rightIndex(index);
if (isSmaller(rightChild, leftChild)) {
smallerChild = rightChild;
}
}
if (isSmaller(smallerChild, index)) {
swap(index, smallerChild);
index = smallerChild;
} else {
// heap invariant is maintained
return;
}
}
}
// percolate upwards until heap invariant is maintained
private void heapifyUp() {
int index = this.size - 1;
while (hasParent(index)) {
int parent = parentIndex(index);
if (isSmaller(index, parent)) {
swap(index, parent);
index = parent;
} else {
// heap invariant is maintained
return;
}
}
}
// check if heap is empty
public boolean isEmpty() {
return size == 0;
}
// check if heap is full
public boolean isFull() {
return size == heap.length;
}
private boolean isSmaller(int left, int right) {
return heap[left].compareTo(heap[right]) < 0;
}
private boolean hasParent(int i) {
return i > 0;
}
private int leftIndex(int i) {
return (i * 2) + 1;
}
private int rightIndex(int i) {
return (i * 2) + 2;
}
private boolean hasLeftChild(int i) {
return leftIndex(i) < size;
}
private boolean hasRightChild(int i) {
return rightIndex(i) < size;
}
private int parentIndex(int i) {
return (i - 1) / 2;
}
//swap objects at indexes
private void swap(int j, int k) {
Building tmp = new Building(heap[j]);
heap[j] = new Building(heap[k]);
heap[k] = tmp;
}
}