Greetings,
I'm trying to implement a Deque using a circular array that extends when the array gets full. My problem seems to be that the array refuses to extend. Either I am computing size() incorrectly or there is a problem with how I update my front and rear indices. I've looked over it many times and I seem to figure this out. Can anyone help?
public class ArrayDeque
{
public static final int INIT_CAPACITY = 8; // initial array capacity
protected int capacity; // current capacity of the array
protected int front; // index of the front element
protected int rear; // index of the rear element
protected int[] A; // array deque
public ArrayDeque( ) // constructor method
{
A = new int[ INIT_CAPACITY ];
capacity = INIT_CAPACITY;
front = rear = 0;
}
/**
* Display the content of the deque
*/
public void printDeque( )
{
for ( int i = front; i != rear; i = (i+1) % capacity )
System.out.print( A[i] + " " );
System.out.println();
}
/**
* Returns the number of items in this collection.
*/
public int size()
{
return (capacity - front + rear) % capacity;
}
/**
* Returns true if this collection is empty.
*/
public boolean isEmpty()
{
return front == rear;
}
/**
* Returns the first element of the deque
*/
public int getFirst() throws EmptyDequeException
{
if(isEmpty()){
throw new EmptyDequeException("Deque is empty.");
}
return A[front % capacity];
}
/**
* Returns the last element of the deque
*/
public int getLast() throws EmptyDequeException
{
if(isEmpty()){
throw new EmptyDequeException("Deque is empty.");
}
return A[(rear - 1) % capacity];
}
/**
* Inserts e at the beginning (as the first element) of the deque
* If array is full, extend array by doubling its capacity and insert element in new array
*/
public void insertFirst(int e)
{
if(size() == capacity){
int[] B = new int[2*capacity];
for(int i = 0; i < size(); i++){
B[i] = A[i];
}
A = B;
}
int[] B = new int[capacity];
for(int i = 0; i < size(); i++){
B[i] = A[i];
}
A = B;
for(int i = size(); i >= front; i--){
A[i+1] = A[i];
}
A[front] = e;
rear = (rear + 1) % capacity;
}
/**
* Inserts e at the end (as the last element) of the deque
* If array is full, extend array by doubling its capacity and insert element in new array
*/
public void insertLast(int e)
{
if(size() == capacity){
capacity *= 2;
int[] B = new int[capacity];
for(int i = 0; i < size(); i++){
B[i] = A[i];
}
A = B;
}
A[rear] = e;
rear = (rear + 1) % capacity;
}
/**
* Removes and returns the first element of the deque
* Shrink array by half of current size N when number of elements in the deque falls below N/4
* minimum capacity should always be 8
*/
public int removeFirst() throws EmptyDequeException
{
if(isEmpty()){
throw new EmptyDequeException("Deque is empty.");
}
else if(capacity >= 8){
if(size() < capacity/4){
capacity /= 2;
int[] B = new int[capacity];
for(int i = 0; i < size(); i++){
B[i] = A[i];
}
A = B;
}
}
int temp = A[front];
A[front] = 0;
front = (front + 1) % capacity;
return temp;
}
/**
* Removes and returns the last element of the deque
* Shrink array by half of current size N when number of elements in the deque falls below N/4
* minimum capacity should always be 8
*/
public int removeLast() throws EmptyDequeException
{
if(isEmpty()){
throw new EmptyDequeException("Deque is empty.");
}
else if(capacity >= 8){
if(size() < capacity/4){
int[] B = new int[capacity/2];
for(int i = 0; i < capacity; i++){
B[i] = A[i];
}
A = B;
}
}
int temp = A[rear - 1];
A[rear] = 0;
rear = (rear - 1) % capacity;
return temp;
}
} // end class
Test Input:
for(i = 1; i <= 100; i++)
q.insertLast(i);
q.printDeque();
for(i = 1; i <= 99; i++)
k = q.removeFirst();
q.printDeque();
Test Output: I've set up several print statements and the size always remains at 7 for some reason...
Exception in thread "main" A3.EmptyDequeException: Deque is empty.
at A3.ArrayDeque.removeFirst(ArrayDeque.java:133)
at A3.ArrayMain.main(ArrayMain.java:37)
Well, consider this...
If your max capacity is 8, then your queue can have 9 total size states: 0 1 2 3 4 5 6 7 and 8.
ANY_NUMBER % 8 can only have 8 states: 0 1 2 3 4 5 6 and 7.
This is homework (thanks for being honest about it) so I don't want to spoil it all for you, but this should point you in the right direction. Good luck!
Look at your insertFirst method, and what does it do when the array is full. Read the whole method, not only the first if block. Are you ever changing your capacity?
Related
Merge function seems to be not working, l1.size() == 0 gives me concurrent Modification Problem. How can I correct this function?
public static List<Integer> merge(List<Integer> l1, List<Integer> l2){
if(l1.size()==0) {
return l2;
}
else if(l2.size()==0)
return l1;
else {
if(l1.get(0) < l2.get(0)) {
int removed = l1.remove(0);
List<Integer> l3 = merge(l1,l2);
l3.add(0,removed);
return l3;
}
else {
int removed = l2.remove(0);
List<Integer> l3 = merge(l1,l2);
l3.add(0,removed);
return l3;
}
}
}
Here is an implementation of mergesort for a generic ArrayList
/**
* perform a merge sort on the elements of data
*
*
* #param data data != null, all elements of data are the same data type
* #TimeComplexity: O(NlogN)
*/
private void mergeSort(ArrayList<E> data) {
if (data == null) {
throw new IllegalArgumentException("paramater data cannot be null");
}
// creates new arrayList and initializes data.size() nulls
ArrayList<E> temp = new ArrayList<E>();
for (int i = 0; i < data.size(); i++) {
temp.add(null);
}
// sorts using recursion
sort(data, temp, 0, data.size() - 1);
}
/**
* helper method for merge sort
*
*
* #TimeComplexity: O(NlogN)
*/
private void sort(ArrayList<E> data, ArrayList<E> temp, int low, int high) {
// if we can keep merging and sorting
if (low < high) {
int center = (low + high) / 2;
// two recursion calls to split and merge the two splits
sort(data, temp, low, center);
sort(data, temp, center + 1, high);
merge(data, temp, low, center + 1, high);
}
}
/**
* helper method for merge sort
*
*
* #TimeComplexity: O(N)
*/
private void merge(ArrayList<E> data, ArrayList<E> temp, int leftPos, int rightPos, int rightEnd) {
int leftEnd = rightPos - 1;
int tempPos = leftPos;
int numElements = rightEnd - leftPos + 1;
// main loop
while (leftPos <= leftEnd && rightPos <= rightEnd) {
if (data.get(leftPos).compareTo(data.get(rightPos)) <= 0) {
temp.set(tempPos, data.get(leftPos));
leftPos++;
} else {
temp.set(tempPos, data.get(rightPos));
rightPos++;
}
tempPos++;
}
// copy rest of left half
while (leftPos <= leftEnd) {
temp.set(tempPos, data.get(leftPos));
tempPos++;
leftPos++;
}
// copy rest of right half
while (rightPos <= rightEnd) {
temp.set(tempPos, data.get(rightPos));
tempPos++;
rightPos++;
}
// Copy temp back into data
for (int i = 0; i < numElements; i++, rightEnd--)
data.set(rightEnd, temp.get(rightEnd));
}
I have made a code for array based queue. It is behaving very weirdly, like I have used for loop to enqueue 0,1,2,3,4 but what gets inserted in the queue is 0,0,1,2,3.
Also dequeue is throwing ArrayOutOfBoundsException, and I don't know why.
The logic for enqueueing I have used is that I put elements as in a simple array. One thing extra is that I increase the capacity of the array if size comes near to half of the capacity.
For dequeueing I am decreasing the capacity if the size is less than one third of the capacity. Also I am keeping a counter for popped, which pops the elements from starting of the array.
The following is the code I have used:
class ArrayQueue {
private int[] arr;
private int size;
private int capacity;
private int popped = 0;
public ArrayQueue(int capacity) {
this.capacity = capacity;
size = 0;
arr = new int[capacity];
}
public int size() {
return size;
}
public int capacity() {
return capacity;
}
public void enqueue(int ele) {
size++;
if(size >= capacity/2) {
capacity = capacity*2;
int[] nArr = new int[capacity];
for(int i=0;i<size;i++)
nArr[i] = arr[i];
arr = nArr;
}
arr[size] = ele;
}
public void dequeue() {
size--;
System.out.println(arr[popped]+" removed");
if(size <= capacity/3) {
capacity = capacity/2;
int[] nArr = new int[capacity];
for(int i=0;i<size;i++)
nArr[i] = arr[i];
arr = nArr;
}
int[] nArr = new int[capacity];
for(int i=0;i<popped;i++)
nArr[i] = arr[i];
for(int i=popped+1;i<size;i++)
nArr[i-1] = arr[i];
arr = nArr;
popped++;
}
public boolean isEmpty() {
return (size == 0);
}
public void showQueue() {
for(int i=0;i<size;i++)
System.out.println("| "+arr[i]+" |");
}
}
public static void main(String[] args) {
ArrayQueue a = new ArrayQueue(10);
System.out.println("Starting size "+a.size());
for(int i=0;i<5;i++) {
a.enqueue(i);
System.out.println("Current size is "+a.size());
System.out.println("Current capacity is "+a.capacity());
}
System.out.println();
a.showQueue();
System.out.println();
a.dequeue();
System.out.println("Size: "+a.size());
System.out.println("Current capacity is "+a.capacity());
a.dequeue();
System.out.println("Size: "+a.size());
System.out.println("Current capacity is "+a.capacity());
a.dequeue();
System.out.println("Size: "+a.size());
System.out.println("Current capacity is "+a.capacity());
a.dequeue();
System.out.println("Size: "+a.size());
System.out.println("Current capacity is "+a.capacity());
}
The output I am getting is:
Starting size 0
Current size is 1
Current capacity is 10
Current size is 2
Current capacity is 10
Current size is 3
Current capacity is 10
Current size is 4
Current capacity is 10
Current size is 5
Current capacity is 20
| 0 |
| 0 |
| 1 |
| 2 |
| 3 |
0 removed
Size: 4
Current capacity is 10
1 removed
Size: 3
Current capacity is 5
0 removed
Size: 2
Current capacity is 5
0 removed
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at ArrayQueue.dequeue(Code.java:228)
at Code.main(Code.java:76)
When you do deQueue() operation, you should always remove an element at index 0. So you no need increment popped. It should be always 0 (index 0)
public void dequeue() {
size--;
System.out.println(arr[popped] + " removed");
if (size <= capacity / 3) {
capacity = capacity / 2;
int[] nArr = new int[capacity];
for (int i = 0; i < size; i++)
nArr[i] = arr[i];
arr = nArr;
}
int[] nArr = new int[capacity];
/* for (int i = 0; i < popped; i++)
nArr[i] = arr[i]; //Not required as popped is always 0
*/
for (int i = popped + 1; i < size; i++)
nArr[i - 1] = arr[i];
arr = nArr;
//popped++; // not required as we remove first element
}
For enqueue your code should like this. in your code it has problem when you increment size before.
public void enqueue(int ele) {
if(size >= capacity/2) {
capacity = capacity*2;
int[] nArr = new int[capacity];
for(int i=0;i<size;i++)
nArr[i] = arr[i];
arr = nArr;
}
arr[size] = ele;
size++;
}
and For Dequeue you should not do Operation based on Popped every time you need to remove 0 index.
public void dequeue() {
System.out.println(arr[0] + " removed");
if (size <= capacity / 3) {
capacity = capacity / 2;
int[] nArr = new int[capacity];
for (int i = 0; i < size; i++)
nArr[i] = arr[i];
arr = nArr;
}
int[] nArr = new int[capacity];
for (int i = 1; i < size; i++) // every time we need to pop first index
nArr[i - 1] = arr[i];
arr = nArr;
popped++;
size--;
}
I have been given the code below for ArrayList and have to write a new method in this class that will remove all of a given value from the ArrayList. I have been trying to write this function but for some reason cannot figure out how to access the list. I had to do the same thing for an LLList so I called the head node but I do not understand how to access the Array.
/*
* ArrayList.java
*
*/
import java.util.*;
/*
* A class that implements our simple List interface using an array.
*/
public class ArrayList implements List {
private Object[] items; // the items in the list
private int length; // # of items in the list
/*
* Constructs an ArrayList object with the specified maximum size
* for a list that is initially empty.
*/
public ArrayList(int maxSize) {
items = new Object[maxSize];
length = 0;
}
/*
* Constructs an ArrayList object containing the items in the specified
* array, and with a max size that is twice the size of that array
* (to allow room for growth).
*/
public ArrayList(Object[] initItems) {
items = new Object[2 * initItems.length];
for (int i = 0; i < initItems.length; i++) {
items[i] = initItems[i];
}
length = initItems.length;
}
/*
* length - returns the number of items in the list
*/
public int length() {
return length;
}
/*
* isFull - returns true if the list is full, and false otherwise
*/
public boolean isFull() {
return (length == items.length);
}
/* getItem - returns the item at position i in the list */
public Object getItem(int i) {
if (i < 0 || i >= length) {
throw new IndexOutOfBoundsException();
}
return items[i];
}
/*
* addItem - adds the specified item at position i in the list,
* shifting the items that are currently in positions i, i+1, i+2,
* etc. to the right by one. Returns false if the list is full,
* and true otherwise.
*/
public boolean addItem(Object item, int i) {
if (i < 0 || i > length) {
throw new IndexOutOfBoundsException();
} else if (isFull()) {
return false;
}
// make room for the new item
for (int j = length - 1; j >= i; j--) {
items[j + 1] = items[j];
}
items[i] = item;
length++;
return true;
}
/*
* removeItem - removes the item at position i in the list,
* shifting the items that are currently in positions i+1, i+2,
* etc. to the left by one. Returns a reference to the removed
* object.
*/
public Object removeItem(int i) {
if (i < 0 || i >= length) {
throw new IndexOutOfBoundsException();
}
Object removed = items[i];
// fill in the "hole" left by the removed item
for (int j = i; j < length - 1; j++) {
items[j] = items[j + 1];
}
items[length - 1] = null;
length--;
return removed;
}
/*
* toString - converts the list into a String of the form
* {item0, item1, ...}
*/
public String toString() {
String str = "{";
for (int i = 0; i < length; i++) {
str = str + items[i];
if (i < length - 1) {
str = str + ", ";
}
}
str = str + "}";
return str;
}
/*
* iterator - returns an iterator for this list
*/
public ListIterator iterator() {
// still needs to be implemented
return null;
}
To help you out a little more, here is a naive solution (it could be more efficient) that makes use of the given removeItem function. Just read it and try to understand it otherwise you'll have trouble down the line, if you have a question about it then feel free to ask.
public void removeAll(Object o) {
int i = 0;
while (i < length) {
if (o.equals(items[i])) {
removeItem(i);
} else {
i++;
}
}
}
And to test it:
public static void main(String[] args) {
ArrayList list = new ArrayList(10);
list.addItem("1", 0);
list.addItem("3", 1);
list.addItem("2", 2);
list.addItem("2", 3);
list.addItem("4", 4);
list.addItem("1", 5);
list.addItem("2", 6);
System.out.println(list);
// {1, 3, 2, 2, 4, 1, 2}
list.removeAll("2");
System.out.println(list);
// {1, 3, 4, 1}
}
The code attached below is suppose to produce this output:
The array is: 4 3 6 9 3 9 5 4 1 9
This array DOES contain 5.
Sorted by Arrays.sort(): 1 3 3 4 4 5 6 9 9 9
Sorted by Sweep Sort: 1 3 3 4 4 5 6 9 9 9
Sorted by Selection Sort: 1 3 3 4 4 5 6 9 9 9
Sorted by Insertion Sort: 1 3 3 4 4 5 6 9 9 9
But it doesn't. I followed the instruction in the book that I am reading and it didn't help. Can I get your opinion on what those errors might be? I'm not asking for solutions, I want to be pointed in the right direction as to where the errors are and what type of errors they are.
import java.util.Arrays;
/**
* This class looks like it's meant to provide a few public static methods
* for searching and sorting arrays. It also has a main method that tests
* the searching and sorting methods.
*
* TODO: The search and sort methods in this class contain bugs that can
* cause incorrect output or infinite loops. Use the Eclipse debugger to
* find the bugs and fix them
*/
public class BuggySearchAndSort {
public static void main(String[] args) {
int[] A = new int[10]; // Create an array and fill it with small random ints.
for (int i = 0; i < 10; i++)
A[i] = 1 + (int)(10 * Math.random());
int[] B = A.clone(); // Make copies of the array.
int[] C = A.clone();
int[] D = A.clone();
System.out.print("The array is:");
printArray(A);
if (contains(A,5))
System.out.println("This array DOES contain 5.");
else
System.out.println("This array DOES NOT contain 5.");
Arrays.sort(A); // Sort using Java's built-in sort method!
System.out.print("Sorted by Arrays.sort(): ");
printArray(A); // (Prints a correctly sorted array.)
bubbleSort(B);
System.out.print("Sorted by Bubble Sort: ");
printArray(B);
selectionSort(C);
System.out.print("Sorted by Selection Sort: ");
printArray(C);
insertionSort(D);
System.out.print("Sorted by Insertion Sort: ");
printArray(D);
}
/**
* Tests whether an array of ints contains a given value.
* #param array a non-null array that is to be searched
* #param val the value for which the method will search
* #return true if val is one of the items in the array, false if not
*/
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
else
return false;
}
return false;
}
/**
* Sorts an array into non-decreasing order. This inefficient sorting
* method simply sweeps through the array, exchanging neighboring elements
* that are out of order. The number of times that it does this is equal
* to the length of the array.
*/
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; i++) {
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
/**
* Sorts an array into non-decreasing order. This method uses a selection
* sort algorithm, in which the largest item is found and placed at the end of
* the list, then the second-largest in the next to last place, and so on.
*/
public static void selectionSort(int[] array) {
for (int top = array.length - 1; top > 0; top--) {
int positionOfMax = 0;
for (int i = 1; i <= top; i++) {
if (array[1] > array[positionOfMax])
positionOfMax = i;
}
int temp = array[top]; // swap top item with biggest item
array[top] = array[positionOfMax];
array[positionOfMax] = temp;
}
}
/**
* Sorts an array into non-decreasing order. This method uses a standard
* insertion sort algorithm, in which each element in turn is moved downwards
* past any elements that are greater than it.
*/
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top - 1;
while (pos > 0 && array[pos] > temp) {
// move items that are bigger than temp up one position
array[pos+1] = array[pos];
pos--;
}
array[pos] = temp; // place temp into last vacated position
}
}
/**
* Outputs the ints in an array on one line, separated by spaces,
* with a line feed at the end.
*/
private static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(array[i]);
}
System.out.println();
}
}
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; i++) { //<---- wrong increment. it should be j++
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
in this part is at least one error. You should check your loops if your programm does not determine.
I have finished my project and decided to drop a help
public static void main(String[] args) {
int[] A = new int[10]; // Create an array and fill it with small random ints.
for (int i = 0; i < 10; i++)
A[i] = 1 + (int)(10 * Math.random());
int[] B = A.clone(); // Make copies of the array.
int[] C = A.clone();
int[] D = A.clone();
System.out.print("The array is:");
printArray(A);
if (contains(A,5))
System.out.println("This array DOES contain 5.");
else
System.out.println("This array DOES NOT contain 5.");
Arrays.sort(A); // Sort using Java's built-in sort method!
System.out.print("Sorted by Arrays.sort(): ");
printArray(A); // (Prints a correctly sorted array.)
sweepSort(B);
System.out.print("Sorted by Sweep Sort: "); //Changed name
printArray(B);
selectionSort(C);
System.out.print("Sorted by Selection Sort: ");
printArray(C);
insertionSort(D);
System.out.print("Sorted by Insertion Sort: ");
printArray(D);
}
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
//removed else
} //removed return false;
return false;
}
public static void sweepSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; j++) { //'i++' => 'j++'
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
public static void selectionSort(int[] array) {
for (int top = array.length - 1; top > 0; top--) {
int positionOfMax = 0;
for (int i = 1; i <= top; i++) {
if (array[i] > array[positionOfMax]) //replaced [1]
positionOfMax = i;
}
int temp = array[top]; // swap top item with biggest item
array[top] = array[positionOfMax];
array[positionOfMax] = temp;
}
}
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top - 1;
while (pos >= 0 && array[pos] >= temp) { // '>' => '>='
// move items that are bigger than temp up one position
array[pos+1] = array[pos];
pos--;
}
array[pos+1] = temp; // place temp into last vacated position //added '+1'
}
}
private static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(array[i]);
}
System.out.println();
}
}
Thank for all your help guys. Using the debugger I found the for main issues
Error 1:
public static void sweepSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; i++) {<------// need change i++ to j++
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
Error 2 and 3:
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top - 1;
while (pos > 0 && array[pos] > temp) { //<----- need to change '>' to '>='
// move items that are bigger than temp up one position
array[pos+1] = array[pos];
pos--;
}
array[pos ] = temp; // place temp into last vacated position // <------------------------need to change 'array[pos ]' to 'array[pos + 1]'
}
}
Error 4:
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
else //<---------- need to remove this
return false; //<---------- need to remove this
}
return false;
}
package sort;
import java.util.Arrays;
/**
* This class looks like it's meant to provide a few public static methods
* for searching and sorting arrays. It also has a main method that tests
* the searching and sorting methods.
*
* TODO: The search and sort methods in this class contain bugs that can
* cause incorrect output or infinite loops. Use the Eclipse debugger to
* find the bugs and fix them
*/
public class BuggySearchAndSort {
public static void main(String[] args) {
int[] A = new int[10]; // Create an array and fill it with small random ints.
for (int i = 0; i < 10; i++)
A[i] = 1 + (int)(10 * Math.random());
int[] B = A.clone(); // Make copies of the array.
int[] C = A.clone();
int[] D = A.clone();
System.out.print("The array is:");
printArray(A);
if (contains(A,5))
System.out.println("This array DOES contain 5.");
else
System.out.println("This array DOES NOT contain 5.");
Arrays.sort(A); // Sort using Java's built-in sort method!
System.out.print("Sorted by Arrays.sort(): ");
printArray(A); // (Prints a correctly sorted array.)
bubbleSort(B);
System.out.print("Sorted by Bubble Sort: ");
printArray(B);
selectionSort(C);
System.out.print("Sorted by Selection Sort: ");
printArray(C);
insertionSort(D);
System.out.print("Sorted by Insertion Sort: ");
printArray(D);
}
/**
* Tests whether an array of ints contains a given value.
* #param array a non-null array that is to be searched
* #param val the value for which the method will search
* #return true if val is one of the items in the array, false if not
*/
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
}
return false;
}
/**
* Sorts an array into non-decreasing order. This inefficient sorting
* method simply sweeps through the array, exchanging neighboring elements
* that are out of order. The number of times that it does this is equal
* to the length of the array.
*/
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; j++) {
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
/**
* Sorts an array into non-decreasing order. This method uses a selection
* sort algorithm, in which the largest item is found and placed at the end of
* the list, then the second-largest in the next to last place, and so on.
*/
public static void selectionSort(int[] array) {
for (int top = array.length - 1; top > 0; top--) {
int positionOfMax = 0;
for (int i = 0; i <= top; i++) {
if (array[i] > array[positionOfMax])
positionOfMax = i;
}
int temp = array[top]; // swap top item with biggest item
array[top] = array[positionOfMax];
array[positionOfMax] = temp;
}
}
/**
* Sorts an array into non-decreasing order. This method uses a standard
* insertion sort algorithm, in which each element in turn is moved downwards
* past any elements that are greater than it.
*/
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top ;
while (pos > 0 && array[pos-1] >= temp) {
// move items that are bigger than temp up one position
array[pos] = array[pos-1];
pos--;
}
array[pos] = temp; // place temp into last vacated position
}
}
/**
* Outputs the ints in an array on one line, separated by spaces,
* with a line feed at the end.
*/
private static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(array[i]);
}
System.out.println();
}
}
I'm trying to implement a priority queue that allows for deletion of the min and the max values. I'm doing this by creating two heaps within the PQ object and two additional arrays to keep track of the location of the same values in each heap. I'm confused about how to maintain those two arrays when performing a sink, swim, or exchange.
Online, I found the comparison of the two arrays to be a[N] = b[ab[N]] and b[N] = a[ba[N]], but the problem is I don't understand those equations. If someone can offer me some insight, I think I would then be able to maintain the arrays.
Here's my code so far:
public class MyMinMaxPQ<Key extends Comparable<Key>> {
private int N = 0; // number of items on priority queue
private Key[] a; // minheap
private Key[] b; // maxheap
private int[] ab; // index a to b: a[i] == b[ab[i]]
private int[] ba; // index b to a: b[i] == a[ba[i]]
public MyMinMaxPQ(int maxN) { //constructor
a = (Key[]) new Comparable[maxN+1];
b = (Key[]) new Comparable[maxN+1];
ab = new int[maxN+1];
ba = new int[maxN+1];
}
public Key delMin() {
Key min = b[1];
exch(b, 1, N--);
a[N+1] = null;
sink(a, 1);
return min;
}
public Key delMax() {
Key max = a[1]; // Retrieve max key from top.
exch(a, 1, N--); // Exchange with last item.
a[N+1] = null; // Avoid loitering.
sink(a, 1); // Restore heap property.
return max;
}
public void insert(Key item) {
a[++N] = item;
b[++N] = item;
swim(a, N);
swim(b, N);
a[N] = b[ab[N]];
b[N] = a[ba[N]];
}
private void swim(Key[] heap, int k) {
while (k > 1 && less(heap, k/2, k)) {
exch(heap, k/2, k);
k = k/2;
}
}
/**
* Moves the numbers down the heap
* #param heap the heap that the sink will occur on
* #param k the index number on the heap
*/
private void sink(Key[] heap, int k) {
while (2*k <= N) {
int j = 2*k;
if (j < N && less(heap, j, j+1)) j++;
if (!less(heap, k, j)) break;
exch(heap, k, j);
k = j;
}
}
/**
* #param i = first integer to be compared
* #param j = second integer to be compared
* #return <0 : i precedes j; =0 : i and j are equal; >0 : j precedes i
*/
private boolean less(Key[] heap, int i, int j) {
if (heap == a) {
return a[i].compareTo(a[j]) <= 0;
} else {
return b[i].compareTo(b[j]) >= 0;
}
}
/** exchange the two values at indexes i and j in the same heap */
private void exch(Key[] heap, int i, int j) {
Key t = heap[i];
heap[i] = heap[j];
heap[j] = t;
}
/** Is the priority queue empty? */
public boolean isEmpty() {
return N == 0;
}
/** Return the number of items on the priority queue. */
public int size() {
return N;
}
}