-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHeap (Winter 19 Exam)
249 lines (223 loc) · 7.5 KB
/
Heap (Winter 19 Exam)
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import java.io.*;
import java.util.LinkedList;
import java.util.Scanner;
import java.lang.Math;
import java.lang.Integer;
import java.lang.String;
class Main {
public static void main(String[] args) {
// Uncomment the following two lines if you want to read from a file
In.open("public/test3.in");
Out.compareTo("public/test3.out");
MaxHeap heap = new MaxHeap();
//
// Read the number of test cases, and start executing
//
int T = In.readInt();
for (int test = 0; test < T; test += 1) {
//
// Read the command from the input
//
int command = In.readInt();
if (command == 1) {
//
// If command is '1' then, we must read an array from the input
// then, build a heap out of the array, using the 'buildHeap'
// method, and finally, output the heap on the screen.
//
heap.readHeap();
heap.buildHeap();
heap.writeHeap();
} else if (command == 2) {
//
// if the command is set to '2', then we read the heap values,
// which already have partial order that satisfies the heap
// property. Then we read we insert M elements, reading the
// M number first.
//
heap.readHeap();
int M = In.readInt();
for (int i = 0; i < M; i += 1) {
heap.insert(In.readInt());
}
heap.writeHeap();
} else if (command == 3) {
//
// if the command is set to '3', then we read the heap values,
// which already have partial order that satisfies the heap
// property. Then we delete the maximum elements M times,
// after reading the M number first.
//
heap.readHeap();
int M = In.readInt();;
for (int i = 0; i < M; i += 1) {
heap.deleteMax();
}
heap.writeHeap();
}
}
// Uncomment the following line if you want to read from a file
// In.close();
}
}
class MaxHeap {
//
// We assume that the heap will not exceed MAX_HEAPSIZE length
//
final static int MAX_HEAPSIZE = 100000;
//
// This field describes the number of elements that the heap holds
//
private int N = 0;
//
// The values of the heap are stored in this array
//
private int values[] = new int [MAX_HEAPSIZE];
//
// Default empty constructor
//
public MaxHeap () {
// do nothing ...
}
//
// Helper function that provides comparison.
//
private boolean cmp(int a, int b) {
return a < b;
}
//
// Helper function that swaps the i-th & the j-th element of the heap
//
private void swap (int i, int j) {
int tmp = values[i];
values[i] = values[j];
values[j] = tmp;
}
//
// The heap will read the values. In this function,
// we assume that the values have partial order that satisfies the heap
// condition.
//
public void readHeap () {
N = In.readInt();
for (int i = 0; i < N; i += 1) {
values[i] = In.readInt();
}
}
//
// Helper function that is used in printing the state of the heap.
//
public void writeHeap () {
if (N > 0) {
Out.print(values[0]);
for (int i = 1; i < N; i += 1) {
Out.print(" " + values[i]);
}
}
Out.println();
}
// ====================================================================================================================
// Complete the methods below. Feel free to add additional methods / fields if needed.
// ====================================================================================================================
//
// We assume that values are already stored in the values[] array, but they
// do not hold the heap condition and have arbitrary order. We need to
// restore the heap condition using the method below.
//
public void buildHeap () {
//
// Your code goes here ...
//
int startIdx = (this.N / 2) - 1;
//Out.println("Size of values is " + this.values.length);
for (int i=startIdx;i>=0;i--){
this.heapify(this.values, N, i);
}
/*//for each element in the array, swap it with its biggest child, stop before leaves
for (int i=values.length-1;i>0;i--){
int parentIndex;
//if index of child is even, index of parent is minus 2 divided by 2
if (i%2==0){
parentIndex = (i-2)/2;
}
//if index of child is odd, index of parent is minus 1 divided by 2
else{
parentIndex = (i-1)/2;
}
//if parent is smaller than child
if (values[parentIndex]<values[i]){
//swap em
this.swap(i,parentIndex);
}
}*/
}
static void heapify(int array[], int size, int i)
{
int largest = i; // Initialize current node as largest
int left = 2 * i + 1; // position of left child in array = 2*i + 1
int right = 2 * i + 2; // position of right child in array = 2*i + 2
if (left < size && array[left] > array[largest]) // If left child is larger than root
largest = left;
if (right < size && array[right] > array[largest]) // If right child is larger than largest so far
largest = right;
if (largest != i) { // If largest is not root swap it
int swap = array[i];
array[i] = array[largest];
array[largest] = swap;
heapify(array, size, largest); // Recursively heapify the sub-tree
}
}
//
// Inserts a value in the heap, and places it on the right positions such
// that the heap condition holds.
//
public void insert(int value) {
//
// Your code goes here ...
//
//add to end of heap, call heapify on heap
values[N] = value;
siftUp(N);
N++;
/*int startIdx = (this.N / 2) - 1;
for (int i=startIdx; i>=0; i--) {
this.heapify(this.values, N, i);
}
*/
}
public void siftUp(int i){
int parentIndex;
//if index of child is even, index of parent is minus 2 divided by 2
if (i%2==0){
parentIndex = (i-2)/2;
}
//if index of child is odd, index of parent is minus 1 divided by 2
else{
parentIndex = (i-1)/2;
}
//if parent is smaller than child
if (i>0 && values[parentIndex]<values[i]){
//swap em
this.swap(i,parentIndex);
siftUp(parentIndex);
}
}
public void siftDownRoot(){
heapify(this.values, this.N,0);
}
//
// Pops the first value from the heap, restoring the heap condition
//
public void deleteMax () {
//
// Your code goes here ...
//
values[0]=values[N-1];
values[N-1]=0;
N--;
this.siftDownRoot();
}
// ====================================================================================================================
// End of implementation
// ====================================================================================================================
}