-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMinHeap.java
167 lines (142 loc) · 4.45 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
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
159
160
161
162
163
164
165
166
167
import java.util.NoSuchElementException;
/**
* Your implementation of a MinHeap.
*/
public class MinHeap<T extends Comparable<? super T>> {
/**
* The initial capacity of the MinHeap.
*
* DO NOT MODIFY THIS VARIABLE!
*/
public static final int INITIAL_CAPACITY = 13;
/*
* Do not add new instance variables or modify existing ones.
*/
private T[] backingArray;
private int size;
/**
* This is the constructor that constructs a new MinHeap.
*
* Recall that Java does not allow for regular generic array creation,
* so instead we cast a Comparable[] to a T[] to get the generic typing.
*/
public MinHeap() {
//DO NOT MODIFY THIS METHOD!
backingArray = (T[]) new Comparable[INITIAL_CAPACITY];
}
/**
* Adds an item to the heap. If the backing array is full (except for
* index 0) and you're trying to add a new item, then double its capacity.
*
* Method should run in amortized O(log n) time.
*
* @param data The data to add.
* @throws java.lang.IllegalArgumentException If the data is null.
*/
public void add(T data) {
// WRITE YOUR CODE HERE (DO NOT MODIFY METHOD HEADER)!
if (data == null) {
throw new IllegalArgumentException(" Cannot add null to MinHeap.");
}
size++;
if(size + 1 > backingArray.length) {
resize();
}
backingArray[size] = data;
upheap();
}
/**
* Removes and returns the min item of the heap. As usual for array-backed
* structures, be sure to null out spots as you remove. Do not decrease the
* capacity of the backing array.
*
* Method should run in O(log n) time.
*
* @return The data that was removed.
* @throws java.util.NoSuchElementException If the heap is empty.
*/
public T remove() {
// WRITE YOUR CODE HERE (DO NOT MODIFY METHOD HEADER)!
if(size == 0){
throw new IllegalArgumentException("Cannot remove from an empty MinHeap.");
}
T data = backingArray[1];
backingArray[1] = backingArray[size];
backingArray[size] = null;
size--;
downheap();
return data;
}
/**
* Returns the backing array of the heap.
*
* For grading purposes only. You shouldn't need to use this method since
* you have direct access to the variable.
*
* @return The backing array of the list
*/
public T[] getBackingArray() {
// DO NOT MODIFY THIS METHOD!
return backingArray;
}
/**
* Returns the size of the heap.
*
* For grading purposes only. You shouldn't need to use this method since
* you have direct access to the variable.
*
* @return The size of the list
*/
public int size() {
// DO NOT MODIFY THIS METHOD!
return size;
}
private void resize() {
T[] newArray = (T[]) new Comparable[backingArray.length * 2];
for (int i = 0; i < backingArray.length; i++) {
newArray[i] = backingArray[i];
}
backingArray = newArray;
}
private void upheap() {
for (int child = size; child > 1; child /= 2) {
int parent = child / 2;
if (isSmaller(child, parent)) {
swap(child, parent);
} else {
break;
}
}
}
private void downheap() {
int parent = 1;
while (hasLeftChild(parent)) {
int leftChild = parent * 2;
int rightChild = (parent * 2) + 1;
int smallerChild = leftChild;
if (hasRightChild(parent) && isSmaller(rightChild, leftChild)) {
smallerChild = rightChild;
}
if (isSmaller(smallerChild, parent)) {
swap(smallerChild, parent);
} else {
break;
}
parent = smallerChild;
}
}
private void swap(int indexA, int indexB) {
T temp = backingArray[indexA];
backingArray[indexA] = backingArray[indexB];
backingArray[indexB] = temp;
}
private boolean isSmaller(int indexA, int indexB) {
return backingArray[indexA].compareTo(backingArray[indexB]) < 0;
}
private boolean hasRightChild(int index) {
return (index * 2) + 1 <= size;
}
private boolean hasLeftChild(int index) {
return (index * 2) <= size;
}
}