BubbleDown function(min heap) not working - java

I have generated a minheap to this file but I think something I have missed but I can't identify what are the things I have missed. I have missed something on --private void bubbleDown() { }-- section but I can't find what are the things missed by me.
private int default_size = 100; // how big the heap should be
private T[] array;
private int size;
public Heap() {
#SuppressWarnings("unchecked")
T[] tmp = (T[]) (new Comparable[default_size]);
array = tmp;
size = 0;
}
boolean isRoot(int index) { return (index == 0); }
int leftChild(int index) { return 2 * index + 1; }
int parent(int index) { return (index - 1) / 2; }
int rightChild(int index) { return 2 * index + 2; }
T myParent(int index) { return array[parent(index)]; }
T myLeftChild(int index) { return array[leftChild(index)]; }
T myRightChild(int index) { return array[rightChild(index)]; }
boolean hasLeftChild(int i) { return leftChild(i) < size-1; }
boolean hasRightChild(int i){ return rightChild(i) < size-1; }
private void swap(int a, int b) {
T tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
public boolean isEmpty() { return (size == 0); }
/* adding heap */
public void add(T value) {
if(size == default_size) throw new IllegalStateException("Full array");
array[size++] = value;
bubbleUp();
}
public void bubbleUp() {
if(size == 0) throw new IllegalStateException("Shape error");
int index = size - 1;
while(!isRoot(index)) {
if(myParent(index).compareTo(array[index]) <= 0) break;
/* else part */
swap(parent(index), index);
index = parent(index);
}
}
/* removing */
public T remove() {
if(isEmpty()) return null;
T res = array[0]; /* root */
array[0] = array[size-1];
size --;
bubbleDown();
return res;
}
// i think this section having wrong something
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 >= default_size || array[leftChild] == null) return -1;
if (array[leftChild].compareTo(array[rightChild]) <= 0 || (array[rightChild] == null))
return leftChild;
return rightChild;
}
public void show() {
for(int i=0; i<size; i++)
System.out.print(array[i] + " ");
System.out.println("=======");
}
public static void main(String [] args) {
Heap<Integer> heap = new Heap<Integer>();
for(int i=0; i<10; i++) {
heap.add((Integer)(int)(Math.random() * 100));
heap.show();
}
System.out.println("You should see sorted numbers");
while(!heap.isEmpty()) {
System.out.print(heap.remove());
System.out.print(" ");
heap.show();
}
System.out.println();
}
}
this code used generics and min heap functions.. i need to identify what is the wrong thing did by me on bubbleDown() section

Explanation
The bubbleDown() method is not a different way to insert a node and move it to it's correct position in the Heap. When bubbleDown() is called it's job is to Heapify the Binary Tree from any state. So your attempt to write the method just by changing the condition from the bubbleUp() method isn't gonna help you.
Extra
Here is a video that can give you the idea of how bubbleDown is supposed to work.

Related

How does one replace last element of full stack with new element? (java)

public class ourStack1 {
private int elements[];
private int index; // indicate the next position to put a new data
private int size;
public ourStack1() {
elements = new int[10];
index = 0;
size = 0;
}
public void push(int value) {
if(size == 10) {
System.out.println("Stack is full, no push");
return;
}
elements[index] = value;
++index;
++size;
}
public int pop() {
if(size == 0) {
System.out.println("Stack is empty, no pop");
return -1;
}
int temp = elements[index - 1];
--index;
--size;
return temp;
}
public int peek() {
if(size == 0) {
System.out.println("Stack is empty, no peek");
return -1;
}
return elements[index - 1];
}
/*
public int mySize() {
// you know how to do this
}
*/
public static void main(String[] args) {
ourStack1 x = new ourStack1();
for(int i = 0; i < 10; ++i)
x.push(i);
for(int i = 0; i < 10; ++i)
System.out.println(x.pop());
}
}
I'm confused on how to overwrite the last element added to the full stack. I want to add element to replace the last element while not exceeding the array size[10]
public void replaceLast(int value) {
if (this.size > 0) {
this.pop();
}
this.push(value);
}

Heap based priority queue implementation

I've made a priority queue implementation that uses heap, but it works somewhat but I've encountered a problem where if I dequeue the priority queue it doesn't heapify correctly.
For example if I input 10 elements from an array ranging from 0 - 9, since this is a MaxHeap implementation it should always return the highest value and then heapify to correct the tree but it doesn't.
When I dequeue and get 9 and I don't get 8 when I dequeue again, I instead get 0 because it swaps from the last index but it doesn't fix the tree.
I've tried debugging and unit testing but I simply can't find where the problem is. I was wondering if some fresh eyes could see what I could not, thanks in advance!
import java.lang.reflect.Array;
public class HeapPriorityQueue<T extends Comparable<? super T>> implements PriorityQueue<T> {
private Class<T> clazz;
private int lastIndex, capacity;
private T heap[];
public HeapPriorityQueue(Class<T> clazz, int capacity) {
this.clazz = clazz;
this.capacity = capacity;
this.heap = (T[]) Array.newInstance(clazz, capacity);
this.lastIndex = -1;
}
#Override
public void clear() {
this.lastIndex = -1;
this.heap = (T[]) Array.newInstance(clazz, capacity);
System.out.println("The queue has been destroyed!");
}
#Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return lastIndex == -1;
}
#Override
public boolean isFull() {
// TODO Auto-generated method stub
return lastIndex == capacity-1;
}
#Override
public int size() {
// TODO Auto-generated method stub
return lastIndex;
}
#Override
public void enqueue(T element) {
if (!isFull()) {
heap[++lastIndex] = element;
shiftUp();
String test = "";
for (int i = 0; i < heap.length; i++) {
test += "" + heap[i] + " ";
}
System.out.println(test);
}
}
#Override
public T dequeue() {
if(isEmpty()) throw new QueueEmptyException();
T rootValue = heap[0];
swap(0, lastIndex);
heap[lastIndex] = null;
lastIndex--;
shiftDown();
String test = "";
for (int i = 0; i < heap.length; i++) {
test += "" + heap[i] + " ";
}
System.out.println(test);
return rootValue;
}
#Override
public T getFront() {
if(isEmpty()) throw new QueueEmptyException();
return heap[0];
}
private void shiftUp() {
int index = lastIndex;
int parentIndex = parent(index);
while (parentIndex > -1 && heap[index].compareTo(heap[parentIndex]) > 0) {
swap(index, parentIndex);
index = parentIndex;
parentIndex = parent(parentIndex);
}
}
private void shiftDown() {
int index = 0;
while (index < lastIndex) {
T maxValue = heap[index];
int maxIndex = index;
int leftIndex = left(index);
if (leftIndex > 0 && maxValue.compareTo(heap[leftIndex]) > 0) {
maxValue = heap[leftIndex];
maxIndex = leftIndex;
}
int rightIndex = left(index);
if (rightIndex > 0 && maxValue.compareTo(heap[rightIndex]) > 0) {
maxValue = heap[rightIndex];
maxIndex = rightIndex;
}
if (maxIndex == index) {
break;
}
swap(maxIndex, index);
index = maxIndex;
}
}
private int parent(int index) {
return index/2;
}
private int left(int index) {
int leftChild = index * 2;
return leftChild;
}
private int right(int index) {
int rightChild = index * 2 + 1;
return rightChild;
}
private void swap(int index1, int index2) {
T temp = heap[index1];
heap[index1] = heap[index2];
heap[index2 ] = temp;
}
public static void main(String[] args) {
Integer[] data = {1, 2, 5, 6, 7, 8, 9, 10, 15, 20};
HeapPriorityQueue<Integer> pq = new HeapPriorityQueue<Integer>(Integer.class,10);
for (Integer i : data) {
pq.enqueue(i);
}
System.out.println(pq.dequeue());
System.out.println(pq.dequeue());
}
}

Minheapify method

Problem desc:
i seem to have a problem with my MIN-heap structure. I get the nullpointer in the min-heapify method in the first if-statement. The test class doesnt matter in this case
Can anyone spot the error? Here is the code for the minHeap (Line 31 is the first IF statement in the minHeapify method):
public class PQHeap implements PQ {
private PriorityQueue pq;
private Element[] heapArray;
private int heapSize;
public PQHeap(int maxElms) {
pq = new PriorityQueue(maxElms);
heapArray = new Element[maxElms];
heapSize = 0;
}
public void minHeapify(int index) {
int left = getLeft(index);
int right = getRight(index);
int smallest = index;
if (left < heapSize && heapArray[left].getKey() < heapArray[index].getKey()) {
smallest = left;
}
if (right < heapSize && heapArray[right].getKey() < heapArray[smallest].getKey()) {
smallest = right;
}
if (smallest != index) {
exchangeKey(heapArray[index].getKey(), heapArray[smallest].getKey());
minHeapify(smallest);
}
}
public int getLeft(int index) {
return index * 2;
}
public int getRight(int index) {
return index * 2 + 1;
}
public int getParent(int index) {
return index / 2;
}
public void exchangeKey(int a, int b) {
int temp = a;
a = b;
b = temp;
}
#Override
public Element extractMin() {
Element min = heapArray[0];
heapArray[0] = heapArray[heapArray.length - 1];
minHeapify(0);
return min;
}
#Override
public void insert(Element e) {
heapSize++;
int i = heapSize;
heapArray[i] = e;
while (i > 1 && heapArray[getParent(i)].getKey() > heapArray[i].getKey()) {
exchangeKey(heapArray[i].getKey(), getParent(heapArray[i].getKey()));
i = getParent(i);
}
}
//SKAL FJERNES
public void print() {
for (int i = 1; i <= heapSize / 2; i++) {
System.out.print(" PARENT : " + heapArray[i].getKey()
+ " LEFT CHILD : " + heapArray[2 * i].getKey()
+ " RIGHT CHILD :" + heapArray[2 * i + 1].getKey());
System.out.println();
}
}
//SKAL FJERNES
public void minHeap() {
for (int pos = (heapSize / 2); pos >= 1; pos--) {
minHeapify(pos);
}
}
}

Heap Iterators java

I have this code for a heap tree and I'm stuck with the iterators.
I need in-order, pre-order and post-order iterators, but I have no idea how to do it.
If someone has an idea or example please help.
class Numbers implements Comparable<Numbers> {
private int value;
public Numbers(int value) {
this.value = value;
}
public String toString() {
return Integer.toString(value);
}
public int getValue() {
return this.value;
}
public int compareTo(Numbers o) {
int tmp = o.getValue();
if (value > tmp)
return 1;
if (value < tmp)
return -1;
return 0;
}
}
class BinaryHeapIsFull extends Exception {
BinaryHeapIsFull() {
super("There is no more place in the heap!");
}
}
public class BinaryHeap<E extends Comparable> {
E[] elements;
int count;
public BinaryHeap(int maxSize) {
elements = (E[]) new Comparable[maxSize];
this.count = 0;
}
public void enqueue(E elem) throws BinaryHeapIsFull {
if (count == elements.length)
throw new BinaryHeapIsFull();
int i = count++;
while (i > 0 && elements[(i - 1) / 2].compareTo(elem) == 1) {
elements[i] = elements[(i - 1) / 2];
i = (i - 1) / 2;
}
elements[i] = elem;
}
public E findMin() {
return elements[0];
}
public E dequeueMin() {
if (count == 0)
return null;
E result = elements[0];
E last = elements[--count];
int i = 0;
while (2 * i + 1 <= count) {
int child = 2 * i + 1;
if (child < count
&& elements[child + 1].compareTo(elements[child]) == -1)
child++;
if (last.compareTo(elements[child]) == -1
|| last.compareTo(elements[child]) == 0)
break;
elements[i] = elements[child];
i = child;
}
elements[i] = last;
return result;
}
public String toString() {
String print = "";
for (int i = 0; i < count; i++)
print += elements[i].toString() + " ";
return print;
}
public void sort() {
int a = count;
for (int i = 0; i < a; i++) {
System.out.print(findMin() + " ");
dequeueMin();
}
}
public static void main(String[] args) throws BinaryHeapIsFull {
BinaryHeap<Numbers> b = new BinaryHeap<Numbers>(10);
b.enqueue(new Numbers(6));
System.out.println(b.toString());
b.enqueue(new Numbers(3));
System.out.println(b.toString());
b.enqueue(new Numbers(4));
System.out.println(b.toString());
b.enqueue(new Numbers(1));
System.out.println(b.toString());
b.enqueue(new Numbers(5));
System.out.println(b.toString());
b.enqueue(new Numbers(0));
System.out.println(b.toString());
b.enqueue(new Numbers(2));
System.out.println(b.toString());
b.dequeueMin();
System.out.println(b.toString());
b.dequeueMin();
System.out.println(b.toString());
System.out.println(b.findMin());
b.sort();
}
}
I'd start with three classes, one for each case, that implements the Iterator interface. Give those iterators an instance of your binary heap and let them do their thing.
public class BinaryHeapPreOrderIterator implements Iterator {
// constructor and methods for Iterator here.
}

Problem in implementing Sorted List by Array in Java

There seems to be a problem in add method of the class I have written.. I want to make a SortedList using an array, but I can't figure out what the problem is. This is my code:
public class SortedList {
private Integer[] elements;
private int size;
private int capacity;
public SortedList(int cap) {
elements = new Integer[cap];
if (cap > 0)
{
cap = capacity;
}
else
capacity = 10;
}
public boolean isEmpty()
{
return size == 0;
}
public boolean isFull()
{
return size == capacity;
}
public int size()
{
return size;
}
public void doubleCapacity()
{
capacity = capacity * 2;
}
public void add(Integer el)
{
if(this.isEmpty())
{
elements[0] = el;
size++;
}
else if(this.isFull())
{
this.doubleCapacity();
for(int i = 0; i<this.size(); i++)
{
if(el >= elements[i])
{
elements[i+2] = elements[i+1];
elements[i+1] = el;
}
else
{
elements[i+1] = elements[i];
elements[i] = el;
}
}
size++;
}
else
{
for(int i = 0; i<this.size(); i++)
{
if(el >= elements[i])
{
elements[i+2] = elements[i+1];
elements[i+1] = el;
}
else
{
elements[i+1] = elements[i];
elements[i] = el;
}
}
size++;
}
}
public String toString()
{
String s = "";
s = s + "<SortedList[";
for(int i = 0; i < this.size(); i++)
{
s = s + elements[i];
if(i < this.size()-1)
s = s + ",";
}
s = s + "]>";
return s;
}
public static void main(String[] args)
{
SortedList sl = new SortedList(5);
sl.add(3);
//sl.add(2);
sl.add(4);
sl.add(5);
// sl.add(6);
System.out.println(sl.toString());
}
}
My code works if I only add 2 Integers to my list, but when I try to add the numbers 3,4,5 then I get 3,5,5...
What can be the problem? Thanks..
public class SortedList {
private Integer[] elements;
private int size=0;
private int capacity;
public SortedList(int cap) {
elements = new Integer[cap];
if (cap > 0)
{
capacity = cap;
}
else
capacity = 10;
}
public boolean isEmpty()
{
return size == 0;
}
public boolean isFull()
{
return size == capacity;
}
public int size()
{
return size;
}
public void doubleCapacity()
{
capacity = capacity * 2;
}
public void add(Integer el) throws Exception{
elements[size] = el;
size++;
if(size>capacity){
throw new Exception("Size Exceeded");
}
}
public String toString()
{
sort();
String s = "";
s = s + "<SortedList[";
for(int i = 0; i < this.size(); i++)
{
s = s + elements[i];
if(i < this.size()-1)
s = s + ",";
}
s = s + "]>";
return s;
}
public void sort(){
for (int i=0; i <size()-1; i++) {
if (elements[i] > elements[i+1]) {
// exchange elements
int temp = elements[i];
elements[i] = elements[i+1];
elements[i+1] = temp;
}
}
}
public static void main(String[] args)
{
try {
SortedList sl = new SortedList(5);
sl.add(3);
//sl.add(2);
sl.add(6);
sl.add(5);
// sl.add(6);
System.out.println(sl.toString());
} catch (Exception ex) {
Logger.getLogger(SortedList.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Your insertion code doesn't work.
elements[i+1] = elements[i];
elements[i] = el;
What happens to the old value of elements[i+1]?
I'd recommend the following changes to the previous solution. If you're only calling sort in toString(), your list is going to get out of order quickly in cases where you have multiple unsorted elements in a row (Now you could remove sort() from toString()). It's essentially a quick insertion sort that dies as soon as it can't make any more swaps down the list. Again, as dty suggested, a faster choice would be a binary search to find the insertion point.
public void doubleCapacity(){
capacity = capacity * 2;
Integer temp[] = new Integer[capacity];
for (int i = 0; i < size; i++){
temp[i] = elements[i];
}
elements = temp;
}
public void add(Integer el){
if(size+1>capacity){
doubleCapacity();
}
elements[size] = el;
size++;
sort();
}
public void sort(){
//Iterates down the list until it's sorted.
for (int i=size()-2; i >= 0 && (elements[i] < elements[i+1]); i--) {
// exchange elements
int temp = elements[i];
elements[i] = elements[i+1];
elements[i+1] = temp;
}
}

Categories

Resources