Skip to content

Commit d8f361b

Browse files
Merge pull request TheAlgorithms#7 from Nicolas040/master
Heaps
2 parents 3bba193 + 4338456 commit d8f361b

File tree

5 files changed

+411
-0
lines changed

5 files changed

+411
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
*
3+
*/
4+
package heaps;
5+
6+
/**
7+
* @author Nicolas Renard
8+
* Exception to be thrown if the getElement method is used on an empty heap.
9+
*
10+
*/
11+
@SuppressWarnings("serial")
12+
public class EmptyHeapException extends Exception {
13+
14+
public EmptyHeapException(String message) {
15+
super(message);
16+
}
17+
18+
}

data_structures/heaps/Heap.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package heaps;
2+
3+
/**
4+
* Interface common to heap data structures.<br>
5+
* <p>Heaps are tree-like data structures that allow storing elements in a specific
6+
* way. Each node corresponds to an element and has one parent node (except for the root) and
7+
* at most two children nodes. Every element contains a key, and those keys
8+
* indicate how the tree shall be built. For instance, for a min-heap, the key of a node shall
9+
* be greater than or equal to its parent's and lower than or equal to its children's (the opposite rule applies to a
10+
* max-heap).</p>
11+
* <p>All heap-related operations (inserting or deleting an element, extracting the min or max) are performed in
12+
* O(log n) time.</p>
13+
* @author Nicolas Renard
14+
*
15+
*
16+
*/
17+
public interface Heap {
18+
19+
/**
20+
*
21+
* @return the top element in the heap, the one with lowest key for min-heap or with
22+
* the highest key for max-heap
23+
* @throws Exception if heap is empty
24+
*/
25+
public abstract HeapElement getElement() throws EmptyHeapException;
26+
/**
27+
* Inserts an element in the heap. Adds it to then end and toggle it until it finds its
28+
* right position.
29+
*
30+
* @param element an instance of the HeapElement class.
31+
*/
32+
public abstract void insertElement(HeapElement element);
33+
34+
/**
35+
* Delete an element in the heap.
36+
*
37+
* @param elementIndex int containing the position in the heap of the element to be deleted.
38+
*/
39+
public abstract void deleteElement(int elementIndex);
40+
41+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
*
3+
*/
4+
package heaps;
5+
6+
import java.lang.Double;
7+
import java.lang.Object;
8+
9+
/**
10+
* Class for heap elements.<br>
11+
* <p>A heap element contains two attributes: a key which will be used to build the tree (int
12+
* or double, either primitive type or object) and any kind of IMMUTABLE object the user sees fit
13+
* to carry any information he/she likes. Be aware that the use of a mutable object might
14+
* jeopardize the integrity of this information. </p>
15+
* @author Nicolas Renard
16+
*
17+
*/
18+
public class HeapElement {
19+
private final double key;
20+
private final Object additionalInfo;
21+
22+
// Constructors
23+
24+
/**
25+
*
26+
* @param key : a number of primitive type 'double'
27+
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
28+
* additional information of use for the user
29+
*/
30+
public HeapElement(double key, Object info) {
31+
this.key = key;
32+
this.additionalInfo = info;
33+
}
34+
35+
/**
36+
*
37+
* @param key : a number of primitive type 'int'
38+
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
39+
* additional information of use for the user
40+
*/
41+
public HeapElement(int key, Object info) {
42+
this.key = key;
43+
this.additionalInfo = info;
44+
}
45+
46+
/**
47+
*
48+
* @param key : a number of object type 'Integer'
49+
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
50+
* additional information of use for the user
51+
*/
52+
public HeapElement(Integer key, Object info) {
53+
this.key = key;
54+
this.additionalInfo = info;
55+
}
56+
57+
/**
58+
*
59+
* @param key : a number of object type 'Double'
60+
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
61+
* additional information of use for the user
62+
*/
63+
public HeapElement(Double key, Object info) {
64+
this.key = key;
65+
this.additionalInfo = info;
66+
}
67+
68+
/**
69+
*
70+
* @param key : a number of primitive type 'double'
71+
*/
72+
public HeapElement(double key) {
73+
this.key = key;
74+
this.additionalInfo = null;
75+
}
76+
77+
/**
78+
*
79+
* @param key : a number of primitive type 'int'
80+
*/
81+
public HeapElement(int key) {
82+
this.key = key;
83+
this.additionalInfo = null;
84+
}
85+
86+
/**
87+
*
88+
* @param key : a number of object type 'Integer'
89+
*/
90+
public HeapElement(Integer key) {
91+
this.key = key;
92+
this.additionalInfo = null;
93+
}
94+
95+
/**
96+
*
97+
* @param key : a number of object type 'Double'
98+
*/
99+
public HeapElement(Double key) {
100+
this.key = key;
101+
this.additionalInfo = null;
102+
}
103+
104+
// Getters
105+
/**
106+
* @return the object containing the additional info provided by the user.
107+
*/
108+
public Object getInfo() {
109+
return additionalInfo;
110+
}
111+
/**
112+
* @return the key value of the element
113+
*/
114+
public double getKey() {
115+
return key;
116+
}
117+
118+
// Overridden object methods
119+
120+
public String toString() {
121+
return "Key: " + key + " - " +additionalInfo.toString();
122+
}
123+
/**
124+
*
125+
* @param otherHeapElement
126+
* @return true if the keys on both elements are identical and the additional info objects
127+
* are identical.
128+
*/
129+
public boolean equals(HeapElement otherHeapElement) {
130+
return (this.key == otherHeapElement.key) && (this.additionalInfo.equals(otherHeapElement.additionalInfo));
131+
}
132+
}

data_structures/heaps/MaxHeap.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package heaps;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* Heap tree where a node's key is higher than or equal to its parent's and lower than or equal
8+
* to its children's.
9+
* @author Nicolas Renard
10+
*
11+
*/
12+
public class MaxHeap implements Heap {
13+
14+
private final List<HeapElement> maxHeap;
15+
16+
public MaxHeap(List<HeapElement> listElements) throws Exception {
17+
maxHeap = new ArrayList<HeapElement>();
18+
for (HeapElement heapElement : listElements) {
19+
if (heapElement != null) insertElement(heapElement);
20+
else System.out.println("Null element. Not added to heap");
21+
}
22+
if (maxHeap.size() == 0) System.out.println("No element has been added, empty heap.");
23+
}
24+
25+
// Get the element at a given index. The key for the list is equal to index value - 1
26+
public HeapElement getElement(int elementIndex) {
27+
if ((elementIndex <= 0) && (elementIndex > maxHeap.size())) throw new IndexOutOfBoundsException("Index out of heap range");
28+
return maxHeap.get(elementIndex - 1);
29+
}
30+
31+
// Get the key of the element at a given index
32+
private double getElementKey(int elementIndex) {
33+
return maxHeap.get(elementIndex - 1).getKey();
34+
}
35+
36+
// Swaps two elements in the heap
37+
private void swap(int index1, int index2) {
38+
HeapElement temporaryElement = maxHeap.get(index1 - 1);
39+
maxHeap.set(index1 - 1, maxHeap.get(index2 - 1));
40+
maxHeap.set(index2 - 1, temporaryElement);
41+
}
42+
43+
// Toggle an element up to its right place as long as its key is lower than its parent's
44+
private void toggleUp(int elementIndex) {
45+
double key = maxHeap.get(elementIndex - 1).getKey();
46+
while (getElementKey((int) Math.floor(elementIndex/2)) < key) {
47+
swap(elementIndex, (int) Math.floor(elementIndex/2));
48+
elementIndex = (int) Math.floor(elementIndex/2);
49+
}
50+
}
51+
52+
// Toggle an element down to its right place as long as its key is higher
53+
// than any of its children's
54+
private void toggleDown(int elementIndex) {
55+
double key = maxHeap.get(elementIndex - 1).getKey();
56+
boolean wrongOrder = (key < getElementKey(elementIndex*2)) || (key < getElementKey(Math.min(elementIndex*2, maxHeap.size())));
57+
while ((2*elementIndex <= maxHeap.size()) && wrongOrder) {
58+
// Check whether it shall swap the element with its left child or its right one if any.
59+
if ((2*elementIndex < maxHeap.size()) && (getElementKey(elementIndex*2 + 1) > getElementKey(elementIndex*2))) {
60+
swap(elementIndex, 2*elementIndex + 1);
61+
elementIndex = 2*elementIndex + 1;
62+
}
63+
else {
64+
swap(elementIndex, 2*elementIndex);
65+
elementIndex = 2*elementIndex;
66+
}
67+
wrongOrder = (key < getElementKey(elementIndex*2)) || (key < getElementKey(Math.min(elementIndex*2, maxHeap.size())));
68+
69+
}
70+
}
71+
72+
private HeapElement extractMax() {
73+
HeapElement result = maxHeap.get(0);
74+
deleteElement(0);
75+
return result;
76+
}
77+
78+
@Override
79+
public void insertElement(HeapElement element) {
80+
maxHeap.add(element);
81+
toggleUp(maxHeap.size());
82+
83+
}
84+
85+
@Override
86+
public void deleteElement(int elementIndex) {
87+
if (isempty(maxHeap)) throw new EmptyHeapException("Attempt to delete an element from an empty heap");
88+
if ((elementIndex > maxHeap.size()) && (elementIndex <= 0)) throw new IndexOutOfBoundsException("Index out of heap range");
89+
// The last element in heap replaces the one to be deleted
90+
maxHeap.set(elementIndex - 1, getElement(maxHeap.size()));
91+
maxHeap.remove(maxHeap.size());
92+
// Shall the new element be moved up...
93+
if (getElementKey(elementIndex) > getElementKey((int) Math.floor(elementIndex/2))) toggleUp(elementIndex);
94+
// ... or down ?
95+
else if (((2*elementIndex <= maxHeap.size()) && (getElementKey(elementIndex) < getElementKey(elementIndex*2))) ||
96+
((2*elementIndex < maxHeap.size()) && (getElementKey(elementIndex) < getElementKey(elementIndex*2)))) toggleDown(elementIndex);
97+
}
98+
99+
@Override
100+
public HeapElement getElement() throws EmptyHeapException {
101+
try {
102+
return extractMax();
103+
} catch (Exception e) {
104+
throw new EmptyHeapException("Heap is empty. Error retrieving element");
105+
}
106+
}
107+
108+
}
109+
110+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy