-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMaxHeap.java
More file actions
158 lines (137 loc) · 3.01 KB
/
MaxHeap.java
File metadata and controls
158 lines (137 loc) · 3.01 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package ds;
/**
* Implementation of a generic Max Heap.
*
* @author shivam.maharshi
*/
@SuppressWarnings("unchecked")
public class MaxHeap<T extends Comparable<T>> {
private T[] arr;
private int size = 0;
private static int DEFAULT_CAPACITY = 101;
public MaxHeap() {
this(DEFAULT_CAPACITY);
}
public MaxHeap(int capacity) {
this.arr = (T[]) (new Object[capacity + 1]);
}
public int size() {
return size;
}
public T getParent(int index) {
validateIndex(index);
return arr[index / 2];
}
public T getLeft(int index) {
validateIndex(index);
if (index * 2 > arr.length - 1) {
return null;
}
return arr[2 * index];
}
public T getRight(int index) {
validateIndex(index);
if (index * 2 + 1 > arr.length - 1) {
return null;
}
return arr[2 * index + 1];
}
public void insert(T value) {
if (isFull()) {
throw new RuntimeException("Can't insert in a full heap.");
}
size++;
arr[size] = value;
siftUp(size);
}
/**
* Checks the parent all the way up to the root for insertion.
*
* @param index
*/
private void siftUp(int index) {
if (index == 0)
return;
int p = parent(index);
if (arr[index].compareTo(arr[p]) > 1) {
swap(index, p);
siftUp(p);
}
}
public T extract() {
if (isEmpty()) {
throw new RuntimeException("Can't extract from empty heap.");
}
T result = arr[1];
arr[1] = arr[size];
size--;
buildHeap();
return result;
}
public boolean isEmpty() {
return size == 0;
}
public boolean isFull() {
return size == arr.length;
}
private void validateIndex(int index) {
if (index < 0) {
throw new IllegalArgumentException("Index can't be negative.");
}
if (index > arr.length) {
throw new IllegalArgumentException("Index can't exceed maximum size.");
}
}
/**
* Restore the heap property for all nodes.
*
* Complexity is O(n * log(n)).
*/
private void buildHeap() {
for (int i = size / 2; i >= 1; i--) {
heapify(i);
}
}
/**
* This method is responsible for restoring the heap property for the
* element at the given index.
*
* PreCondition: All the subtrees of the index satisfy heap property.
*
* Post Condition: All the subtrees including the one at the index satisfy
* heap property.
*
* Complexity is O(log(n)).
*
* @param index
*/
private void heapify(int index) {
int l = left(index);
int r = right(index);
int largest = index;
if (l < size && arr[l].compareTo(arr[index]) > 0) {
largest = l;
}
if (r < size && arr[r].compareTo(arr[largest]) > 0) {
largest = r;
}
if (largest != index) {
swap(index, largest);
heapify(largest);
}
}
private void swap(int a, int b) {
T temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
private int parent(int index) {
return index / 2;
}
private int left(int index) {
return index * 2;
}
private int right(int index) {
return index * 2 + 1;
}
}