Skip to content

Commit a3c5778

Browse files
committed
Rename Heap to BianryHeap. Make Heap an interface.
1 parent 96caa63 commit a3c5778

File tree

10 files changed

+347
-303
lines changed

10 files changed

+347
-303
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,13 @@ Except for code, you can click the `book` and `blog` links for more information.
6969
[`blog`](https://www.jianshu.com/p/b1ab4a170c3c)
7070
+ [LRUCacheSimple](https://github.com/jingedawang/Algorithms/blob/master/src/cache/LRUCacheSimple.java)
7171
+ [Container](https://github.com/jingedawang/Algorithms/tree/master/src/container)
72+
+ [BinaryHeap](https://github.com/jingedawang/Algorithms/blob/master/src/container/BinaryHeap.java)
73+
[`book`](https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf#page=172)
74+
+ [BinarySearchTree](https://github.com/jingedawang/Algorithms/blob/master/src/container/BinarySearchTree.java)
75+
[`book`](https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf#page=307)
7276
+ [BTree](https://github.com/jingedawang/Algorithms/blob/master/src/container/BTree.java)
7377
[`book`](https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf#page=505)
7478
[`blog`](https://zhuanlan.zhihu.com/p/342999669)
75-
+ [BinarySearchTree](https://github.com/jingedawang/Algorithms/blob/master/src/container/BinarySearchTree.java)
76-
[`book`](https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf#page=307)
77-
+ [Heap](https://github.com/jingedawang/Algorithms/blob/master/src/container/Heap.java)
78-
[`book`](https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf#page=172)
7979
+ [PriorityQueue](https://github.com/jingedawang/Algorithms/blob/master/src/container/PriorityQueue.java)
8080
[`book`](https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf#page=183)
8181
+ [RedBlackTree](https://github.com/jingedawang/Algorithms/blob/master/src/container/RedBlackTree.java)

src/container/BinaryHeap.java

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
/**
2+
* Copyright 2022 jingedawang
3+
*/
4+
package container;
5+
6+
/**
7+
* BinaryHeap is basically a binary tree, whose each sub-tree keeps the max or min value in the root node.
8+
*
9+
* The underlying data is stored in an array, which is good for quick access.
10+
* After the heap is built, the values are stored layer by layer in the array. For example, an array
11+
* [4, 8, 1, 2, 0, 6, 5, 1, 9, 3]
12+
* represents a heap like
13+
* <pre>
14+
* +--------------0---------------+
15+
* +------1-------+ +------1-------+
16+
* +--2---+ +--3---+ +--6---+ +--5---+
17+
* 4 9 8
18+
* </pre>
19+
* To save time, we won't maintain a tree structure all the time. If you need to access the data by traversing
20+
* its nodes, please call {@code toBinaryTree} method, which will return as a structured binary tree.
21+
*/
22+
public class BinaryHeap extends AbstractTree implements BinaryTree, Heap {
23+
24+
/**
25+
* Construct an empty max heap.
26+
*/
27+
public BinaryHeap() {
28+
this(new int[0], false);
29+
}
30+
31+
/**
32+
* Construct a heap with given array.
33+
*
34+
* @param arr The data used for constructing the heap.
35+
* @param isMinHeap A flag indicating whether to create a min heap or a max heap.
36+
*/
37+
public BinaryHeap(int[] arr, boolean isMinHeap) {
38+
this.isMinHeap = isMinHeap;
39+
data = arr.clone();
40+
capacity = data.length;
41+
size = data.length;
42+
for (int i = size / 2 - 1; i >= 0; i--) {
43+
if (isMinHeap) {
44+
minHeapify(i);
45+
} else {
46+
maxHeapify(i);
47+
}
48+
}
49+
}
50+
51+
/**
52+
* Check if the heap has no elements.
53+
*
54+
* @return {@code true} if the heap has no elements, {@code false} otherwise.
55+
*/
56+
@Override
57+
public boolean empty() {
58+
return size == 0;
59+
}
60+
61+
/**
62+
* Get the size of the heap.
63+
*
64+
* @return The element count of the heap.
65+
*/
66+
@Override
67+
public int size() {
68+
return size;
69+
}
70+
71+
/**
72+
* Get the top value of the heap.
73+
*
74+
* If this is a max heap, the return value is the maximum.
75+
* If this is a min heap, the return value is the minimum.
76+
*
77+
* @return The top value of the heap.
78+
*/
79+
@Override
80+
public int top() {
81+
return data[0];
82+
}
83+
84+
/**
85+
* Insert a node into the heap.
86+
*
87+
* The node will be inserted to a proper location in the heap.
88+
* @param newNode The node to be inserted.
89+
*/
90+
@Override
91+
public void insert(Node newNode) {
92+
if (size >= capacity) {
93+
int[] newArr;
94+
if (capacity > 0) {
95+
newArr = new int[capacity * 2];
96+
System.arraycopy(data, 0, newArr, 0, size);
97+
} else {
98+
newArr = new int[8];
99+
}
100+
data = newArr;
101+
capacity = newArr.length;
102+
}
103+
size++;
104+
if (isMinHeap) {
105+
data[size - 1] = Integer.MAX_VALUE;
106+
decreaseValue(size - 1, newNode.value);
107+
}
108+
else {
109+
data[size - 1] = Integer.MIN_VALUE;
110+
increaseValue(size - 1, newNode.value);
111+
}
112+
}
113+
114+
/**
115+
* Delete a node from the heap.
116+
*
117+
* Since the heap doesn't maintain the tree structure, so deleting a node from a heap is meaningless. Also, it's not
118+
* useful to delete a node from a heap.
119+
*
120+
* @param node The node to be deleted.
121+
*/
122+
@Override
123+
public void delete(Node node) {
124+
throw new UnsupportedOperationException("'delete' method not supported in BinaryHeap class");
125+
}
126+
127+
/**
128+
* Get and remove the top value of the heap.
129+
*
130+
* If this is a max heap, the return value is the maximum.
131+
* If this is a min heap, the return value is the minimum.
132+
* The top node will be removed and the heap will be maintained.
133+
*
134+
* @return The top value of the heap.
135+
*/
136+
@Override
137+
public int pop() {
138+
if (size <= 0) {
139+
throw new ArrayIndexOutOfBoundsException("Can not pop a value from an empty heap.");
140+
}
141+
int top = data[0];
142+
data[0] = data[size - 1];
143+
size--;
144+
if (isMinHeap) {
145+
minHeapify(0);
146+
}
147+
else {
148+
maxHeapify(0);
149+
}
150+
return top;
151+
}
152+
153+
/**
154+
* Construct the tree structure and return as a binary tree.
155+
*
156+
* @return A binary tree converted from the heap.
157+
*/
158+
public BinaryTree toBinaryTree() {
159+
root = constructSubtree(0);
160+
return this;
161+
}
162+
163+
/**
164+
* Adjust the maximum sub-heap to maintain its properties.
165+
*
166+
* @param index The root index of the sub-heap.
167+
*/
168+
private void maxHeapify(int index) {
169+
int l = left(index);
170+
int r = right(index);
171+
int largest;
172+
if (l < size && data[l] > data[index]) {
173+
largest = l;
174+
} else {
175+
largest = index;
176+
}
177+
if (r < size && data[r] > data[largest]) {
178+
largest = r;
179+
}
180+
if (largest != index) {
181+
int temp = data[index];
182+
data[index] = data[largest];
183+
data[largest] = temp;
184+
maxHeapify(largest);
185+
}
186+
}
187+
188+
/**
189+
* Adjust the minimum sub-heap to maintain its properties.
190+
*
191+
* @param index The root index of the sub-heap.
192+
*/
193+
private void minHeapify(int index) {
194+
int l = left(index);
195+
int r = right(index);
196+
int smallest;
197+
if (l < size && data[l] < data[index]) {
198+
smallest = l;
199+
} else {
200+
smallest = index;
201+
}
202+
if (r < size && data[r] < data[smallest]) {
203+
smallest = r;
204+
}
205+
if (smallest != index) {
206+
int temp = data[index];
207+
data[index] = data[smallest];
208+
data[smallest] = temp;
209+
minHeapify(smallest);
210+
}
211+
}
212+
213+
/**
214+
* Increase the value of the specified item and adjust the heap to keep its properties.
215+
* <p>
216+
* The new value must be greater than the original value, or this method would raise an error.
217+
* This method should be called from a max heap.
218+
*
219+
* @param index The index of the specified item.
220+
* @param newValue The new value of the specified item.
221+
*/
222+
private void increaseValue(int index, int newValue) {
223+
if (newValue < data[index]) {
224+
throw new IllegalArgumentException("Only increasing value is allowed.");
225+
}
226+
data[index] = newValue;
227+
while (index > 0 && data[index] > data[parent(index)]) {
228+
int temp = data[index];
229+
data[index] = data[parent(index)];
230+
data[parent(index)] = temp;
231+
index = parent(index);
232+
}
233+
}
234+
235+
/**
236+
* Decrease the value of the specified item and adjust the heap to keep its properties.
237+
* <p>
238+
* The new value must be smaller than the original value, or this method would raise an error.
239+
* This method should be called from a min heap.
240+
*
241+
* @param index The index of the specified item.
242+
* @param newValue The new value of the specified item.
243+
*/
244+
private void decreaseValue(int index, int newValue) {
245+
if (newValue > data[index]) {
246+
throw new IllegalArgumentException("Only decreasing value is allowed.");
247+
}
248+
data[index] = newValue;
249+
while (index > 0 && data[index] < data[parent(index)]) {
250+
int temp = data[index];
251+
data[index] = data[parent(index)];
252+
data[parent(index)] = temp;
253+
index = parent(index);
254+
}
255+
}
256+
257+
/**
258+
* Get the index of the parent node.
259+
*
260+
* @param i The index of the given node.
261+
* @return The index of the parent node.
262+
*/
263+
private int parent(int i) {
264+
return (i - 1) / 2;
265+
}
266+
267+
/**
268+
* Get the index of the left child node.
269+
*
270+
* @param i The index of the given node.
271+
* @return The index of the left child node.
272+
*/
273+
private int left(int i) {
274+
return 2 * i + 1;
275+
}
276+
277+
/**
278+
* Get the index of the right child node.
279+
*
280+
* @param i The index of the given node.
281+
* @return The index of the right child node.
282+
*/
283+
private int right(int i) {
284+
return 2 * (i + 1);
285+
}
286+
287+
/**
288+
* Construct tree structure recursively.
289+
*
290+
* @param index The index of the subtree to be constructed.
291+
* @return The root node of the constructed subtree.
292+
*/
293+
private Node constructSubtree(int index) {
294+
if (index >= size()) {
295+
return null;
296+
}
297+
Node root = new Node(data[index]);
298+
root.left = constructSubtree(left(index));
299+
root.right = constructSubtree(right(index));
300+
return root;
301+
}
302+
303+
// Flag to indicate whether this heap is a min heap or a max heap.
304+
private final boolean isMinHeap;
305+
306+
// Underlying array data.
307+
private int[] data;
308+
309+
// The number of elements in this heap.
310+
private int size;
311+
312+
// The capacity of this heap.
313+
public int capacity;
314+
315+
}

src/container/BinaryTree.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/**
2-
* Copyright 2020 jingedawang
2+
* Copyright 2022 jingedawang
33
*/
44
package container;
55

66
/**
7-
* <h3>Interface for all binary tree classes</h3>
7+
* Interface for all binary tree classes.
88
*/
99
public interface BinaryTree extends Tree {
1010
}

0 commit comments

Comments
 (0)