PriorityQueue/Heap Update - java

Does Java have an easy way to reevaluate a heap once the priority of an object in a PriorityQueue has changed? I can't find any sign of it in Javadoc, but there has to be a way to do it somehow, right? I'm currently removing the object then re-adding it but that's obviously slower than running update on the heap.

You might need to implement such a heap yourself. You need to have some handle to the position of the item in the heap, and some methods to push the item up or down when its priority has changed.
Some years ago I wrote such a heap as part of a school work. Pushing an item up or down is an O(log N) operation. I release the following code as public domain, so you may use it in any way you please. (You might want to improve this class so that instead of the abstract isGreaterOrEqual method the sort order would rely on Java's Comparator and Comparable interfaces, and also would make the class use generics.)
import java.util.*;
public abstract class Heap {
private List heap;
public Heap() {
heap = new ArrayList();
}
public void push(Object obj) {
heap.add(obj);
pushUp(heap.size()-1);
}
public Object pop() {
if (heap.size() > 0) {
swap(0, heap.size()-1);
Object result = heap.remove(heap.size()-1);
pushDown(0);
return result;
} else {
return null;
}
}
public Object getFirst() {
return heap.get(0);
}
public Object get(int index) {
return heap.get(index);
}
public int size() {
return heap.size();
}
protected abstract boolean isGreaterOrEqual(int first, int last);
protected int parent(int i) {
return (i - 1) / 2;
}
protected int left(int i) {
return 2 * i + 1;
}
protected int right(int i) {
return 2 * i + 2;
}
protected void swap(int i, int j) {
Object tmp = heap.get(i);
heap.set(i, heap.get(j));
heap.set(j, tmp);
}
public void pushDown(int i) {
int left = left(i);
int right = right(i);
int largest = i;
if (left < heap.size() && !isGreaterOrEqual(largest, left)) {
largest = left;
}
if (right < heap.size() && !isGreaterOrEqual(largest, right)) {
largest = right;
}
if (largest != i) {
swap(largest, i);
pushDown(largest);
}
}
public void pushUp(int i) {
while (i > 0 && !isGreaterOrEqual(parent(i), i)) {
swap(parent(i), i);
i = parent(i);
}
}
public String toString() {
StringBuffer s = new StringBuffer("Heap:\n");
int rowStart = 0;
int rowSize = 1;
for (int i = 0; i < heap.size(); i++) {
if (i == rowStart+rowSize) {
s.append('\n');
rowStart = i;
rowSize *= 2;
}
s.append(get(i));
s.append(" ");
}
return s.toString();
}
public static void main(String[] args){
Heap h = new Heap() {
protected boolean isGreaterOrEqual(int first, int last) {
return ((Integer)get(first)).intValue() >= ((Integer)get(last)).intValue();
}
};
for (int i = 0; i < 100; i++) {
h.push(new Integer((int)(100 * Math.random())));
}
System.out.println(h+"\n");
while (h.size() > 0) {
System.out.println(h.pop());
}
}
}

PriorityQueue has the heapify method which re-sorts the entire heap, the fixUp method, which promotes an element of higher priority up the heap, and the fixDown method, which pushes an element of lower priority down the heap. Unfortunately, all of these methods are private, so you can't use them.
I'd consider using the Observer pattern so that a contained element can tell the Queue that its priority has changed, and the Queue can then do something like fixUp or fixDown depending on if the priority increased or decreased respectively.

The standard interfaces don't provide an update capability. You have use a custom type that implements this.
And you're right; although the big-O complexity of algorithms that use a heap doesn't change when you remove and replace the top of the heap, their actual run time can nearly double. I'd like to see better built-in support for a peek() and update() style of heap usage.

That's right. PriorityQueue of Java does not offer a method to update priority and it seems that deletion is taking linear time since it does not store objects as keys, as Map does. It in fact accepts same object multiple times.
I also wanted to make PQ offering update operation. Here is the sample code using generics. Any class that is Comparable can be used with it.
class PriorityQueue<E extends Comparable<E>> {
List<E> heap = new ArrayList<E>();
Map<E, Integer> map = new HashMap<E, Integer>();
void insert(E e) {
heap.add(e);
map.put(e, heap.size() - 1);
bubbleUp(heap.size() - 1);
}
E deleteMax() {
if(heap.size() == 0)
return null;
E result = heap.remove(0);
map.remove(result);
heapify(0);
return result;
}
E getMin() {
if(heap.size() == 0)
return null;
return heap.get(0);
}
void update(E oldObject, E newObject) {
int index = map.get(oldObject);
heap.set(index, newObject);
bubbleUp(index);
}
private void bubbleUp(int cur) {
while(cur > 0 && heap.get(parent(cur)).compareTo(heap.get(cur)) < 0) {
swap(cur, parent(cur));
cur = parent(cur);
}
}
private void swap(int i, int j) {
map.put(heap.get(i), map.get(heap.get(j)));
map.put(heap.get(j), map.get(heap.get(i)));
E temp = heap.get(i);
heap.set(i, heap.get(j));
heap.set(j, temp);
}
private void heapify(int index) {
if(left(index) >= heap.size())
return;
int bigIndex = index;
if(heap.get(bigIndex).compareTo(heap.get(left(index))) < 0)
bigIndex = left(index);
if(right(index) < heap.size() && heap.get(bigIndex).compareTo(heap.get(right(index))) < 0)
bigIndex = right(index);
if(bigIndex != index) {
swap(bigIndex, index);
heapify(bigIndex);
}
}
private int parent(int i) {
return (i - 1) / 2;
}
private int left(int i) {
return 2*i + 1;
}
private int right(int i) {
return 2*i + 2;
}
}
Here while updating, I am only increasing the priority (for my implementation) and it is using MaxHeap, so I am doing bubbleUp. One may need to heapify based on requirement.

Depending on the implementation of the data structure, there may not be a faster way. Most PQ/heap algorithms do not provide an update function. The Java implementation may not be any different. Notice that though a remove/insert makes the code slower, it is unlikely to result in code with a different runtime complexity.
Edit: have a look at this thread: A priority queue which allows efficient priority update?

Unfortunately, JDK's Priority Queue doesn't provide updates.
Robert Sedgewick and Kevin Wayne are well known for their algorithms courses in Princeton, and they also wrote Algorithms.
Inside this excellent book, they provide their own implementations for data structures, including updateable priority queues, such as IndexMinPQ.java
Licensed under GPLv3.

You need to implement it yourself. But you don't have to get fancy. The actual massive timesuck of removing the heap item in Java's implementation of remove(Object) is actually indexOf() since it has to iterate the entire list to find the index of the particular object. If you implement your own datastructure you can tell each object the position in the array and even if your implementation isn't anything fancy it'll outperform Java's since each object would know where its located in the array.
Storing that information you can do just the classic remove and add the new item and you'll beat Java by a lot.
The update routine just calls heapify on the particular index. It saves a heapify call, and some constant operations. The bulk of the optimization here is that Java's actual PriorityQueue can't store the index. So remove(Object) is actually a pretty expensive operation within that datastructure. As you're going to have to locate that Object in the list. This particular class reduces the time taken by PriorityQueue to nearly nothing. Though it requires that you implement Heap.Indexed on the items you put in the heap.
import java.util.Arrays;
public class Heap<T extends Heap.Indexed<T>> {
private Indexed[] heap;
private int length = 0;
public Heap() {
heap = new Indexed[12];
}
private void ensureCapacity() {
if (length > heap.length) {
heap = Arrays.copyOf(heap, length * 2);
}
}
public void add(T obj) {
int index = length++;
ensureCapacity();
obj.setIndex(index);
heap[index] = obj;
heapify(index);
}
public T removeAt(int index) {
T result = get(index);
length -= 1;
if ((length > 0) && (index != length)) {
swap(index, length);
heapify(index);
}
result.setIndex(-1);
heap[length] = null;
return result;
}
public T remove(T obj) {
int index = obj.getIndex();
if (index == -1) {
return null;
}
return removeAt(index);
}
public void update(T obj) {
int index = obj.getIndex();
obj.setIndex(-1);
if (index == -1) {
return;
}
heapify(index);
}
public T poll() {
if (length == 0) {
return null;
}
return removeAt(0);
}
public T peek() {
return get(0);
}
public T get(int index) {
return (T) heap[index];
}
public int size() {
return length;
}
protected boolean compare(int first, int last) {
return get(first).compareTo(get(last)) > -1;
}
protected void swap(int i, int j) {
T tmp = (T) heap[i];
heap[i] = (T) heap[j];
heap[j] = tmp;
heap[i].setIndex(i);
heap[j].setIndex(j);
}
public void heapify(int index) {
int parent = (index - 1) / 2;
if (index > 0 && !compare(parent, index)) {
swap(parent, index);
heapify(parent);
return;
}
int left = (index << 1) + 1;
int right = left + 1;
int largest = index;
if (left < length && !compare(largest, left)) {
largest = left;
}
if (right < length && !compare(largest, right)) {
largest = right;
}
if (largest != index) {
swap(largest, index);
heapify(largest);
}
}
public boolean isEmpty() {
return length == 0;
}
public void clear() {
this.length = 0;
Arrays.fill(heap, null);
}
public interface Indexed<I extends Heap.Indexed> extends Comparable<I> {
int getIndex();
void setIndex(int index);
}
}

Related

get kth-largest-element-in-an-array - implemented using maxheap but getting time exceeded in leetcode

I am trying to solve this leetcode challenge . I implemented a MaxHeap and tried to popout the values to get the Kth largest element in the array but I get a time limit exceeded.
Is there any issue with my MaxHeap implementation that it is slow or can this be done in a faster method?
Problem
https://leetcode.com/problems/kth-largest-element-in-an-array/
class Solution {
private int capacity = 10;
private int size = 0;
int items [] = new int[capacity];
//parent = (i-1)/2
//left-child = 2i+1
//right-child = 2i
public int findKthLargest(int[] nums, int k) {
for(int i=0;i<nums.length;i++){
push(nums[i]);
}
//printHeapArray();
for(int i=0; i<k-1; i++){
int val = pop();
System.out.println("max val popped" + val);
// printHeapArray();
}
return peek();
}
private int getLeftChildIndex(int index){
return index*2+1;
}
private int getRightChildIndex(int index) {
return index*2;
}
private int getParentIndex(int index) {
return (index-1)/2;
}
private int leftChild(int index) {
return items[getLeftChildIndex(index)];
}
private int rightChild(int index) {
return items[getRightChildIndex(index)];
}
private int parent(int index) {
return items[getParentIndex(index)];
}
private boolean hasParent(int index){
return getParentIndex(index) >= 0;
}
private boolean hasLeftChild(int index){
return getLeftChildIndex(index) < size;
}
private boolean hasRightChild(int index){
return getRightChildIndex(index) < size;
}
private void swap(int indexOne, int indexTwo) {
int temp = items[indexOne];
items[indexOne] = items[indexTwo];
items[indexTwo] = temp;
}
private void ensureCapacity() {
if(capacity == size -1) {
items = Arrays.copyOf(items, capacity*2);
capacity *= 2;
}
}
public int peek() {
if(size == 0) {
throw new IllegalStateException();
}
return items[0];
}
public void push(int item) {
ensureCapacity();
items[size] = item;
size++;
heapifyUp();
}
private void heapifyUp() {
int index = size - 1;
while(hasParent(index) && parent(index) < items[index]) {
swap(getParentIndex(index), index);
index = getParentIndex(index);
}
}
public int pop() {
if(size == 0 ) throw new IllegalStateException();
int item = items[0];
items[0] = items[size-1];
size--;
heapifyDown();
return item;
}
//1.Compare the children first and find the child you want to compare against with parent
//2.Compare the selected child with its parent to see if it needs to be swapped
private void heapifyDown() {
int index = 0;
while(hasLeftChild(index))
{
int smallerChildIndex = getLeftChildIndex(index);
if(hasRightChild(index) && rightChild(index) > leftChild(index)){
smallerChildIndex = getRightChildIndex(index);
}
if(items[index] > items[smallerChildIndex]) {
break;
}
if(items[smallerChildIndex] > items[index]) {
swap(smallerChildIndex, index);
}
index = smallerChildIndex;
}
}
public void printHeapArray(){
System.out.println(Arrays.toString(items));
}
}
You have an infinite loop, because you're using the wrong formulas for left-child-index and right-child-index.
Look at heapifyDown. The first index tested is 0, and getRightChildIndex() says that it's right child is also at 0*2 == 0.
For heaps with the root at 0, the left and right children of i are at i*2+1 and i*2+2. For heaps with the root at 1 (not your case), the left and right children of i are at i*2 and i*2+1.
Note that if you fix this then your algorithm can work, but it won't be awesome. Appropriate solutions for this problem use quickselect (expected O(n)), a min-heap (O(n * log k)), or a partial heapsort (O(n + k log n)). Yours is like a partial heap sort, but without the O(n) heapify at the start, giving O(n log n).

What is the problem with my code , I am trying to search in the stack with an internall and external method

Write a method to find the position of a given element in a stack counting from the top of the stack. More precisely,
the method should return 0 if the element occurs on the top, 1 if there is another element on top of it, and so on. If
the element occurs several times, the topmost position should be returned. If the element doesn’t occur at all, -1
must be returned.
You are asked to write this method in two different ways; one way is to implement it internally inside the
ArrayStack class and the other way is to implement it externally in a separate class. Important: At the end
the stack should be returned to the original state (i.e. no elements should be removed and the order of the elements
should not change).
This is the externall class
public class Stack{
public static int searchstack(ArrayStack z, int n) {
ArrayStack temp = new ArrayStack(z.size());
int c = 0;
boolean flag = false;
while (!z.isEmpty()) {
if (z.top() == n) {
flag = true;
return c;
}
if (z.top() != n) {
temp.push(z.pop());
c++;
flag = false;
}
}
if (flag == false) {
c = -1;
}
while (!temp.isEmpty() && !z.isFull()) {
z.push(temp.pop());
}
return c;
}
public static void main(String[] args) {
ArrayStack z = new ArrayStack(4);
z.push(3); // first element
z.push(7);// 2nd
z.push(8);// 3rd
z.push(1);// 4th
z.printStack();
int n = 3;
System.out.println("Searching externally for" + " " + n + " " + searchstack(z, n));
System.out.println("Searching internally for" +" "+n+" "+ z.searchfor(n)+" "); //THE ERROR IS HERE
}
}
And this is the ArrayClass
public class ArrayStack {
private int[] theStack;
private int maxSize;
private int top;
public ArrayStack(int s) {
maxSize = s;
theStack = new int[maxSize];
top = -1;
}
public void push(int elem) {
top++;
theStack[top] = elem;
}
public int pop() {
int result = theStack[top];
top--;
return result;
}
public int top() {
return theStack[top];
}
public boolean isFull() {
return (top == (maxSize - 1));
}
public boolean isEmpty() {
return (top == -1);
}
public int size() {
return (top + 1);
}
//HERE IS THE METHOD I IMPLEMENTED INTERNALLY AND CALL IT AT THE STACK CLASS
public int searchfor(int n) {
for (int i = top; i >= 0; i--) {
if (theStack[top] == n) {
return i;
}
}
return -1;
}
public void printStack() {
if (top == -1)
System.out.println("Stack is empty!!\n");
else {
System.out.println(theStack[top] + " <- top");
for (int i = top - 1; i >= 0; i--)
System.out.println(theStack[i]);
System.out.println();
}
}
}
The error appearing at the Stack class is at the last line of calling the searchfor method implemented in the Arraystack class , error says that there is no method implemented in Arraystack with the name searchfor (); thiugh I did implement it .whatseems to be the problem ?
You have a bug in your searchStack() implementation. You are losing elements if you find the one you are looking for and it isn't the topmost one.
How to fix your searchStack() method:
keep popping z until you have an empty ArrayStack. While doing so, add the value to a queue.
create valIndex and assign it -1.
Then go through the queue and remove the items from it and adding them to z. While doing so, check for the last occurence of the desired value and save it in valIndex.
if valIndex equals -1 return it. Else, use following equation to convert it to correct index and return:
valIndex = (z.size - 1) - valIndex

Implement a Set class using an array

My Java assignment is to implement a set class by using an array.
The assignment won't allow me import the set class from the library, so I have to make it on my own. When I tried to print out the array, it prints out numbers in repeats, not unique numbers. I don't know where the problem is, so if you guys can find any errors in my code, it would be great. I tried to add numbers 2, 3, and 4 to the set, so the result should be 2 3 4, but the code shows me 2 3 2 3 2.
I think the source of the problem is from the add method from the set class, but I don't know what the problem is exactly.
import java.util.Arrays;
public final class Set implements SetInterface
{
private int[] set;
private int size;
private int capacity;
public Set(int c)
{
capacity = c;
set = new int[capacity];
size = 0;
}
public boolean contains(int x)
{
boolean contains = false;
for(int i = 0; i<capacity; i++)
{
if(x == set[i])
contains = true;
else
contains = false;
}
return contains;
}
public void add(int x)
{
for(int i = 0; i<capacity; i++)
{
if(!contains(x))
{
if(size == capacity)
{
set = Arrays.copyOf(set,size*2);
}
if(set[i]==0)
{
set[i++] = x;
}
}
}
size++;
}
public boolean remove(int x)
{
boolean remove = false;
for(int i = 0; i < capacity; i++)
{
if(x == set[i])
{
set[i] = set[size -1];
size--;
remove = true;
}
if(isEmpty())
{
remove = false;
}
}
return remove;
}
public void clear()
{
set = null;
size = 0;
}
public int size()
{
return size;
}
public boolean isEmpty()
{
if(size == 0)
return true;
else
return false;
}
public int[] toArray()
{
return Arrays.copyOf(set, capacity);
}
}
This is the driver class that I test my class.
import java.util.Arrays;
public class SetDriver
{
public static void main(String[] args)
{
SetDriver driver = new SetDriver();
Set s1 = new Set(5);
s1.add(2);
s1.add(3);
s1.add(4);
driver.print(s1);
System.out.println("Size: "+s1.size());
}
public static void print(Set s)
{
for(int i = 0; i<s.toArray().length; i++)
{
System.out.print(s.toArray()[i]+" ");
}
System.out.println("");
}
}
The outputs are here:
2 3 2 3 2
Size: 3
There's a likely problem with your contains method. Suppose that you did find a duplicate. What happens is that you assign your variable to true and you continue to iterate. This stomps over the logic entirely; you could have a duplicate but never act on it because your boolean code precludes you from doing so.
Ideally, when you find a match, you must stop iterating and return immediately.
public boolean contains(int value) {
for(int setItem : set) {
if(setItem == value) {
return true;
}
}
return false;
}
You should change add method like this.
public void add(int x) {
if (contains(x))
return;
if (size >= capacity) {
capacity *= 2;
set = Arrays.copyOf(set, capacity);
}
set[size++] = x;
}

Java Ring implementation

I am trying to implement a ring that remembers the last N elements. It adds element and changes the pointer correctly. The get() method must return the newest element added to the ring. I tried to find the logic in the get method with pen and paper and eventually, I managed to do it. However, when I run my code it does not seem so. Thanks for the help in advance.
[1][2][3][4][5] <- In the following example, get(0) has to return 5 and get(1) - 4
Iteration and print
[1][2][3][4][5]
Using the get method - get(0), get(1) ....
[1] [5] [4] [3] [2] - here [1] must be on the right side of [2]
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CircularArrayRing<E> extends AbstractCollection<E> implements Ring<E>
{
private int elements;
private int front;
private E[] ring;
#SuppressWarnings("unchecked")
public CircularArrayRing()
{
ring = (E[]) new Object[10];
front = 0;
}
#SuppressWarnings("unchecked")
public CircularArrayRing(int size)
{
ring = (E[]) new Object[size];
front = 0;
}
#Override
public boolean add(E e)
{
ring[front] = e;
front++;
if(front == ring.length)
{
front = 0;
}
if(elements < ring.length)
{
elements++;
}
return false;
}
#Override
public Iterator<E> iterator()
{
return null;
}
#Override
public int size()
{
return elements;
}
#Override
public E get(int index) throws IndexOutOfBoundsException
{
if(index > elements - 1 || index > ring.length - 1)
{
throw new IndexOutOfBoundsException();
}
else
{
if (index > front)
{
return ring[ring.length + front -index];
}
else
{
return ring[front - index];
}
}
}
}
There are some mistakes with the array index handling.
For example if we look at the base case with just 1 element, the logic calling get(0) is:
front - index = 1 - 0 = 1 -> ArrayIndexOutOfBounds
From this we can see that front should be decreased by 1 to reach the correct index.
Further testing will show that the same fix should be applied also to the other branch of the if and that the condition itself should be >= instead of >.
The correct code inside get would then be:
if (index >= front) {
return ring[ring.length + front - 1 - index];
}
else {
return ring[front - 1 - index];
}
So, after looking a bit better at your implementation, I tried rewriting it.
No need to initialize size and effectiveSize, as their default is 0 as class members.
I think this still does what you want.
public class CircularArrayRing<E> extends AbstractCollection<E>
{
private final E[] ring;
private int size;
private int effectiveSize;
#SuppressWarnings("unchecked")
public CircularArrayRing() {
ring = (E[]) new Object[10];
}
#SuppressWarnings("unchecked")
public CircularArrayRing(final int size) {
ring = (E[]) new Object[size];
}
#Override
public boolean add(final E e) {
if (effectiveSize < ring.length) {
effectiveSize++;
}
if (size >= ring.length) {
size = 0;
}
ring[size++] = e;
return true;
}
#Override
public Iterator<E> iterator() {
return null;
}
#Override
public int size() {
return effectiveSize;
}
public E get(final int index) throws IndexOutOfBoundsException {
if (index < 0 || index > effectiveSize - 1) {
throw new IndexOutOfBoundsException();
}
return ring[effectiveSize - index - 1];
}
}
Java ring?
I thought you guys meant one of these:
https://www.slideshare.net/abhishekabhi1023/java-ring-new
I'm looking for information on how to program this ;(

Comparing attribute of an object in implementation of priority queue

I've attempted to implement a priority queue using an Array of Objects "Queue Items" which have some data (a string), and an integer which is the priority. I am trying to make those items comparable so that when I add a new object to the queue I can iterate through the items and add the new item in the correct location and move all items that are now behind it backwards, however when I add a new item to the queue I get a null pointer exception. I'll include all my code, but the toString method was just copied in from a queue so it won't work as expected.
class QueueItem implements Comparable<QueueItem> {
String data;
int pri;
public QueueItem(String data, int pri) {
this.data = data;
this.pri = pri;
}
#Override
public int compareTo(QueueItem item) {
return this.data.compareTo(item.data);
}
}
public class PriorityQueue implements Queue<String> {
private QueueItem[] arr;
private int frontPos, backPos;
public PriorityQueue() {
arr = new QueueItem[20];
backPos = -1;
frontPos = 0;
}
public boolean isEmpty() {
return frontPos == (backPos + 1) % arr.length;
}
public String front() {
if (frontPos == (backPos + 1) % arr.length)
throw new QueueException("Empty Queue - front");
return arr[frontPos].data;
}
public int frontPri() {
if (frontPos == (backPos + 1) % arr.length)
throw new QueueException("Empty Queue - frontPri");
return arr[frontPos].pri;
}
public void addToPQ(String str, int x) {
if (arr.length==0) {
arr[frontPos] = new QueueItem(str, x);
frontPos++;
return;
}
else {
for (int i = 0; i < arr.length; i++) {
arr[i].compareTo(new QueueItem(str, x));
}
}
}
public void deleteFront() {
if (frontPos==(backPos+1)%arr.length) {
throw new QueueException("Empty Queue - deleteFront");
}
frontPos = (frontPos+1)%arr.length;
}
public String toString() {
if (frontPos == (backPos + 1) % arr.length) {
return "<>";
}
StringBuffer sb = new StringBuffer();
sb.append('<');
int pos = frontPos;
while (pos != backPos) {
sb.append(arr[pos]);
sb.append(',');
pos = (pos + 1) % arr.length;
}
sb.append(arr[backPos]);
sb.append('>');
return (sb.toString());
}
}
public interface Queue<String> {
public void addToPQ(String str, int x);
public void deleteFront();
public String front();
public boolean isEmpty();
public int frontPri();
}
class QueueException extends RuntimeException {
QueueException(String s) {
super("Tried to apply " + s + " to empty queue");
}
}
public class pqTest {
public static void main(String[] args) {
PriorityQueue pQ = new PriorityQueue();
if (pQ.isEmpty()) {
System.out.println("Queue is Empty - isEmpty");
}
pQ.addToPQ("Dog", 4);
pQ.addToPQ("Cat", 20);
pQ.deleteFront();
pQ.addToPQ("Fish", 2);
}
}
The problem is that arr is size 20 so the first element won't even be added through the if statement in your addToPQ method because arr.length != 0. So it will then go to your else statement, which iterates through every single element in arr. But arr has 20 null elements since each spot within the array of QueueItems has not been initialized. So you should change your condition in the if statement to frontPos == 0 and change the terminating condition in your loop to i < frontPos so that the method won't iterate through null elements within arr
public void addToPQ(String str, int x) {
if (frontPos==0) {
arr[frontPos] = new QueueItem(str, x);
frontPos++;
return;
}
else {
QueueItem item = new QueueItem(str, x);
for (int i = 0; i < frontPos; i++) {
arr[i].compareTo(item);
}
}
}
You get NullPointerException, because when you are adding second item, you go to else statment where you iterate over array with one non-null element and 19 nulls. So you need to change your code to check if array element at i is null and if it is, assign new element to it.

Categories