Generic Min Heap Implementation in Java
up vote
1
down vote
favorite
There is a Min-Heap implementation in Java. BubbleUp() and BubbleDown() could have been coded using recursion but I prefer without recursion. Would there be a major difference if had used recursion?
package heap;
import interfaces.queue.PriorityQueue;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Heap<T extends Comparable<T>> implements
PriorityQueue<T>
{
private T elements;
private int size;
private int capacity;
public Heap()
{
this(500);
}
public Heap(int capacity)
{
this.capacity = capacity;
size = 0;
elements = (T) new Comparable[this.capacity];
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size() == 0;
}
@Override
public void add(T data) throws Exception
{
if(size() >= capacity) throw new Exception("Heap is full");
elements[size++] = data;
bubbleUp();
}
private void bubbleUp()
{
int child = size() - 1;
int parent = (child-1)/2;
while(parent >= 0 && elements[child].compareTo(elements[parent]) < 0)
{
swap(child, parent);
child = parent;
parent = (child-1)/2;
}
}
@Override
public T removeMin() throws Exception
{
if(isEmpty()) throw new Exception("Empty heap");
T root = elements[0];
swap(size()-1, 0);
elements[size()-1] = null;
size--;
bubbleDown();
return root;
}
private void bubbleDown()
{
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while(choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if(leftChild >= capacity || elements[leftChild] == null) return -1;
if((elements[leftChild].compareTo(elements[rightChild]) <= 0)|| (elements[rightChild] == null))
return leftChild;
return rightChild;
}
private void swap(int child, int parent)
{
T t = elements[child];
elements[child] = elements[parent];
elements[parent] = t;
}
@Override
public String toString()
{
return Arrays.stream(elements)
.filter(element -> element != null)
.collect(Collectors.toList()).toString();
}
}
java heap priority-queue
add a comment |
up vote
1
down vote
favorite
There is a Min-Heap implementation in Java. BubbleUp() and BubbleDown() could have been coded using recursion but I prefer without recursion. Would there be a major difference if had used recursion?
package heap;
import interfaces.queue.PriorityQueue;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Heap<T extends Comparable<T>> implements
PriorityQueue<T>
{
private T elements;
private int size;
private int capacity;
public Heap()
{
this(500);
}
public Heap(int capacity)
{
this.capacity = capacity;
size = 0;
elements = (T) new Comparable[this.capacity];
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size() == 0;
}
@Override
public void add(T data) throws Exception
{
if(size() >= capacity) throw new Exception("Heap is full");
elements[size++] = data;
bubbleUp();
}
private void bubbleUp()
{
int child = size() - 1;
int parent = (child-1)/2;
while(parent >= 0 && elements[child].compareTo(elements[parent]) < 0)
{
swap(child, parent);
child = parent;
parent = (child-1)/2;
}
}
@Override
public T removeMin() throws Exception
{
if(isEmpty()) throw new Exception("Empty heap");
T root = elements[0];
swap(size()-1, 0);
elements[size()-1] = null;
size--;
bubbleDown();
return root;
}
private void bubbleDown()
{
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while(choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if(leftChild >= capacity || elements[leftChild] == null) return -1;
if((elements[leftChild].compareTo(elements[rightChild]) <= 0)|| (elements[rightChild] == null))
return leftChild;
return rightChild;
}
private void swap(int child, int parent)
{
T t = elements[child];
elements[child] = elements[parent];
elements[parent] = t;
}
@Override
public String toString()
{
return Arrays.stream(elements)
.filter(element -> element != null)
.collect(Collectors.toList()).toString();
}
}
java heap priority-queue
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
There is a Min-Heap implementation in Java. BubbleUp() and BubbleDown() could have been coded using recursion but I prefer without recursion. Would there be a major difference if had used recursion?
package heap;
import interfaces.queue.PriorityQueue;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Heap<T extends Comparable<T>> implements
PriorityQueue<T>
{
private T elements;
private int size;
private int capacity;
public Heap()
{
this(500);
}
public Heap(int capacity)
{
this.capacity = capacity;
size = 0;
elements = (T) new Comparable[this.capacity];
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size() == 0;
}
@Override
public void add(T data) throws Exception
{
if(size() >= capacity) throw new Exception("Heap is full");
elements[size++] = data;
bubbleUp();
}
private void bubbleUp()
{
int child = size() - 1;
int parent = (child-1)/2;
while(parent >= 0 && elements[child].compareTo(elements[parent]) < 0)
{
swap(child, parent);
child = parent;
parent = (child-1)/2;
}
}
@Override
public T removeMin() throws Exception
{
if(isEmpty()) throw new Exception("Empty heap");
T root = elements[0];
swap(size()-1, 0);
elements[size()-1] = null;
size--;
bubbleDown();
return root;
}
private void bubbleDown()
{
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while(choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if(leftChild >= capacity || elements[leftChild] == null) return -1;
if((elements[leftChild].compareTo(elements[rightChild]) <= 0)|| (elements[rightChild] == null))
return leftChild;
return rightChild;
}
private void swap(int child, int parent)
{
T t = elements[child];
elements[child] = elements[parent];
elements[parent] = t;
}
@Override
public String toString()
{
return Arrays.stream(elements)
.filter(element -> element != null)
.collect(Collectors.toList()).toString();
}
}
java heap priority-queue
There is a Min-Heap implementation in Java. BubbleUp() and BubbleDown() could have been coded using recursion but I prefer without recursion. Would there be a major difference if had used recursion?
package heap;
import interfaces.queue.PriorityQueue;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Heap<T extends Comparable<T>> implements
PriorityQueue<T>
{
private T elements;
private int size;
private int capacity;
public Heap()
{
this(500);
}
public Heap(int capacity)
{
this.capacity = capacity;
size = 0;
elements = (T) new Comparable[this.capacity];
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size() == 0;
}
@Override
public void add(T data) throws Exception
{
if(size() >= capacity) throw new Exception("Heap is full");
elements[size++] = data;
bubbleUp();
}
private void bubbleUp()
{
int child = size() - 1;
int parent = (child-1)/2;
while(parent >= 0 && elements[child].compareTo(elements[parent]) < 0)
{
swap(child, parent);
child = parent;
parent = (child-1)/2;
}
}
@Override
public T removeMin() throws Exception
{
if(isEmpty()) throw new Exception("Empty heap");
T root = elements[0];
swap(size()-1, 0);
elements[size()-1] = null;
size--;
bubbleDown();
return root;
}
private void bubbleDown()
{
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while(choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if(leftChild >= capacity || elements[leftChild] == null) return -1;
if((elements[leftChild].compareTo(elements[rightChild]) <= 0)|| (elements[rightChild] == null))
return leftChild;
return rightChild;
}
private void swap(int child, int parent)
{
T t = elements[child];
elements[child] = elements[parent];
elements[parent] = t;
}
@Override
public String toString()
{
return Arrays.stream(elements)
.filter(element -> element != null)
.collect(Collectors.toList()).toString();
}
}
java heap priority-queue
java heap priority-queue
asked 8 hours ago
Hamidur Rahman
486
486
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
I do not endorse recursion when a clean and simple iterative iterative solution is readily available. You did the right thing.
The only problem I have is with compareAndPick
implementation. First, rightChild
is not tested against capacity
, and may cause an out-of-bounds access. Second, testing elements[rightChild]
against null
looks too late (how does compareTo(null)
behave?). Finally, there is really no need to test both an index against capacity
and an object against nullness: index < size
guarantees both.
You may consider renaming compareAndPick
to selectSmallestChild
(and choice
to child
).
Also, I recommend to leave the children computation to compareAndPick
, and have a terser version of bubbleDown
loop:
while ((child = selectSmallestChild(parent)) != -1) {
swap(child, parent);
parent = child;
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209701%2fgeneric-min-heap-implementation-in-java%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
I do not endorse recursion when a clean and simple iterative iterative solution is readily available. You did the right thing.
The only problem I have is with compareAndPick
implementation. First, rightChild
is not tested against capacity
, and may cause an out-of-bounds access. Second, testing elements[rightChild]
against null
looks too late (how does compareTo(null)
behave?). Finally, there is really no need to test both an index against capacity
and an object against nullness: index < size
guarantees both.
You may consider renaming compareAndPick
to selectSmallestChild
(and choice
to child
).
Also, I recommend to leave the children computation to compareAndPick
, and have a terser version of bubbleDown
loop:
while ((child = selectSmallestChild(parent)) != -1) {
swap(child, parent);
parent = child;
}
add a comment |
up vote
0
down vote
I do not endorse recursion when a clean and simple iterative iterative solution is readily available. You did the right thing.
The only problem I have is with compareAndPick
implementation. First, rightChild
is not tested against capacity
, and may cause an out-of-bounds access. Second, testing elements[rightChild]
against null
looks too late (how does compareTo(null)
behave?). Finally, there is really no need to test both an index against capacity
and an object against nullness: index < size
guarantees both.
You may consider renaming compareAndPick
to selectSmallestChild
(and choice
to child
).
Also, I recommend to leave the children computation to compareAndPick
, and have a terser version of bubbleDown
loop:
while ((child = selectSmallestChild(parent)) != -1) {
swap(child, parent);
parent = child;
}
add a comment |
up vote
0
down vote
up vote
0
down vote
I do not endorse recursion when a clean and simple iterative iterative solution is readily available. You did the right thing.
The only problem I have is with compareAndPick
implementation. First, rightChild
is not tested against capacity
, and may cause an out-of-bounds access. Second, testing elements[rightChild]
against null
looks too late (how does compareTo(null)
behave?). Finally, there is really no need to test both an index against capacity
and an object against nullness: index < size
guarantees both.
You may consider renaming compareAndPick
to selectSmallestChild
(and choice
to child
).
Also, I recommend to leave the children computation to compareAndPick
, and have a terser version of bubbleDown
loop:
while ((child = selectSmallestChild(parent)) != -1) {
swap(child, parent);
parent = child;
}
I do not endorse recursion when a clean and simple iterative iterative solution is readily available. You did the right thing.
The only problem I have is with compareAndPick
implementation. First, rightChild
is not tested against capacity
, and may cause an out-of-bounds access. Second, testing elements[rightChild]
against null
looks too late (how does compareTo(null)
behave?). Finally, there is really no need to test both an index against capacity
and an object against nullness: index < size
guarantees both.
You may consider renaming compareAndPick
to selectSmallestChild
(and choice
to child
).
Also, I recommend to leave the children computation to compareAndPick
, and have a terser version of bubbleDown
loop:
while ((child = selectSmallestChild(parent)) != -1) {
swap(child, parent);
parent = child;
}
answered 7 hours ago
vnp
38.3k13096
38.3k13096
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209701%2fgeneric-min-heap-implementation-in-java%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown