| 95 |
Kevin |
1 |
import java.nio.ByteBuffer;
|
|
|
2 |
|
|
|
3 |
/** Max-heap implementation */
|
|
|
4 |
public class MaxHeap {
|
|
|
5 |
private LRUBuffer Heap; // Pointer to the heap array
|
|
|
6 |
private long size; // Number of things in heap
|
|
|
7 |
|
|
|
8 |
private byte[] record1 = new byte[4];
|
|
|
9 |
private byte[] record2 = new byte[4];
|
|
|
10 |
private ByteBuffer buff1;
|
|
|
11 |
private ByteBuffer buff2;
|
|
|
12 |
|
|
|
13 |
/** Constructor supporting preloading of heap contents */
|
|
|
14 |
public MaxHeap(LRUBuffer buf, long size) {
|
|
|
15 |
this.Heap = buf;
|
|
|
16 |
this.size = size;
|
|
|
17 |
}
|
|
|
18 |
|
|
|
19 |
/** @return True if pos a leaf position, false otherwise */
|
|
|
20 |
public boolean isLeaf(long pos) {
|
|
|
21 |
return (pos >= size / 2) && (pos < size);
|
|
|
22 |
}
|
|
|
23 |
|
|
|
24 |
/** @return Position for left child of pos */
|
|
|
25 |
public long leftchild(long pos) {
|
|
|
26 |
assert pos < size / 2 : "Position has no left child";
|
|
|
27 |
return 2 * pos + 1;
|
|
|
28 |
}
|
|
|
29 |
|
|
|
30 |
/** @return Position for right child of pos */
|
|
|
31 |
public long rightchild(long pos) {
|
|
|
32 |
assert pos < (size - 1) / 2 : "Position has no right child";
|
|
|
33 |
return 2 * pos + 2;
|
|
|
34 |
}
|
|
|
35 |
|
|
|
36 |
/** @return Position for parent */
|
|
|
37 |
public long parent(long pos) {
|
|
|
38 |
assert pos > 0 : "Position has no parent";
|
|
|
39 |
return (pos - 1) / 2;
|
|
|
40 |
}
|
|
|
41 |
|
|
|
42 |
/** Heapify contents of Heap */
|
|
|
43 |
public void buildheap() {
|
|
|
44 |
for (long i = size / 2 - 1; i >= 0; i--)
|
|
|
45 |
siftdown(i);
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
/** Put element in its correct place */
|
|
|
49 |
private void siftdown(long pos) {
|
|
|
50 |
assert (pos >= 0) && (pos < size) : "Illegal heap position";
|
|
|
51 |
|
|
|
52 |
while (!isLeaf(pos)) {
|
|
|
53 |
long j = leftchild(pos);
|
|
|
54 |
|
|
|
55 |
// if ((j < (size - 1)) && (Heap[j].compareTo(Heap[j + 1]) < 0))
|
|
|
56 |
// j++; // j is now index of child with greater value
|
|
|
57 |
if (j < (size-1)) {
|
|
|
58 |
Heap.getBytes(record1, j);
|
|
|
59 |
buff1 = ByteBuffer.wrap(record1);
|
|
|
60 |
short val1 = buff1.getShort();
|
|
|
61 |
Heap.getBytes(record2, j+1);
|
|
|
62 |
buff2 = ByteBuffer.wrap(record2);
|
|
|
63 |
short val2 = buff2.getShort();
|
|
|
64 |
if (val1 < val2) {
|
|
|
65 |
j++; // j is now index of child with greater value
|
|
|
66 |
}
|
|
|
67 |
|
|
|
68 |
}
|
|
|
69 |
|
|
|
70 |
// if (Heap[pos].compareTo(Heap[j]) >= 0)
|
|
|
71 |
// return;
|
|
|
72 |
Heap.getBytes(record2, j);
|
|
|
73 |
Heap.getBytes(record1, pos);
|
|
|
74 |
buff1 = ByteBuffer.wrap(record1);
|
|
|
75 |
buff2 = ByteBuffer.wrap(record2);
|
|
|
76 |
short val1 = buff1.getShort();
|
|
|
77 |
short val2 = buff2.getShort();
|
|
|
78 |
if (val1 >= val2)
|
|
|
79 |
return;
|
|
|
80 |
|
|
|
81 |
// DSutil.swap(Heap, pos, j);
|
|
|
82 |
Heap.putBytes(record2, pos);
|
|
|
83 |
Heap.putBytes(record1, j);
|
|
|
84 |
|
|
|
85 |
pos = j; // Move down
|
|
|
86 |
}
|
|
|
87 |
}
|
|
|
88 |
|
|
|
89 |
/** Remove and return maximum value */
|
|
|
90 |
public void removemax() {
|
|
|
91 |
assert size > 0 : "Removing from empty heap";
|
|
|
92 |
|
|
|
93 |
//DSutil.swap(Heap, 0, --size); // Swap maximum with last value
|
|
|
94 |
Heap.getBytes(record1, 0);
|
|
|
95 |
Heap.getBytes(record2, size-1);
|
|
|
96 |
Heap.putBytes(record1, size-1);
|
|
|
97 |
Heap.putBytes(record2, 0);
|
|
|
98 |
|
|
|
99 |
size = size - 1;
|
|
|
100 |
if (size != 0) // Not on last element
|
|
|
101 |
siftdown(0); // Put new heap root val in correct place
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
|
|
|
105 |
// /** @return Current size of the heap */
|
|
|
106 |
// public long heapsize() {
|
|
|
107 |
// return size;
|
|
|
108 |
// }
|
|
|
109 |
|
|
|
110 |
// /** Insert val into heap */
|
|
|
111 |
// public void insert(E val) {
|
|
|
112 |
// assert n < size : "Heap is full";
|
|
|
113 |
// int curr = n++;
|
|
|
114 |
// Heap[curr] = val; // Start at end of heap
|
|
|
115 |
// // Now sift up until curr's parent's key > curr's key
|
|
|
116 |
// while ((curr != 0) && (Heap[curr].compareTo(Heap[parent(curr)]) > 0)) {
|
|
|
117 |
// DSutil.swap(Heap, curr, parent(curr));
|
|
|
118 |
// curr = parent(curr);
|
|
|
119 |
// }
|
|
|
120 |
// }
|
|
|
121 |
|
|
|
122 |
// /** Remove and return element at specified position */
|
|
|
123 |
// public E remove(int pos) {
|
|
|
124 |
// assert (pos >= 0) && (pos < n) : "Illegal heap position";
|
|
|
125 |
// if (pos == (n - 1))
|
|
|
126 |
// n--; // Last element, no work to be done
|
|
|
127 |
// else {
|
|
|
128 |
// DSutil.swap(Heap, pos, --n); // Swap with last value
|
|
|
129 |
// // If we just swapped in a big value, push it up
|
|
|
130 |
// while ((pos > 0) && (Heap[pos].compareTo(Heap[parent(pos)]) > 0)) {
|
|
|
131 |
// DSutil.swap(Heap, pos, parent(pos));
|
|
|
132 |
// pos = parent(pos);
|
|
|
133 |
// }
|
|
|
134 |
// if (n != 0)
|
|
|
135 |
// siftdown(pos); // If it is little, push down
|
|
|
136 |
// }
|
|
|
137 |
// return Heap[n];
|
|
|
138 |
// }
|
|
|
139 |
}
|