LinkedList : Collections.max() throwing NoSuchElementException - java

I am not iterating the LinkedList by any means like scanner or other methods, I am using Collections.max() to get maximum number from the LinkedList.
I have read on Stack Overflow that this exception is thrown due to iterator or scanner or tokenizer, but I am using none of them.
import java.io.*;
import java.util.*;
class TLG {
public static void main(String[] args)throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
LinkedList<Integer> first = new LinkedList<Integer>();
LinkedList<Integer> second = new LinkedList<Integer>();
int cases = Integer.parseInt(br.readLine());
for(int i=1;i<=cases;i++) {
String score = br.readLine();
int number1 = Integer.parseInt(score.split(" ")[0]);
int number2 = Integer.parseInt(score.split(" ")[1]);
int diff = number1 - number2;
if(diff > 0){
first.add(diff);
}
else {
second.add(java.lang.Math.abs(diff));
}
}
Integer max1 = Collections.max(first); // Getting Exception here
Integer max2 = Collections.max(second); // Getting Exception here
if(max1 > max2) {
System.out.println(1+" "+max1);
}
else {
System.out.println(2+" "+max2);
}
}
}

/**
* Returns the maximum element of the given collection, according to the
* <i>natural ordering</i> of its elements. All elements in the
* collection must implement the <tt>Comparable</tt> interface.
* Furthermore, all elements in the collection must be <i>mutually
* comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
* <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
* <tt>e2</tt> in the collection).<p>
*
* This method iterates over the entire collection, hence it requires
* time proportional to the size of the collection.
*
* #param coll the collection whose maximum element is to be determined.
* #return the maximum element of the given collection, according
* to the <i>natural ordering</i> of its elements.
* #throws ClassCastException if the collection contains elements that are
* not <i>mutually comparable</i> (for example, strings and
* integers).
* #throws NoSuchElementException if the collection is empty. <---------------
* #see Comparable
*/
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

you are calling Collections.max() with empty list.

You are not checking against Empty case: So Collections.max() will throw NoSuchElementException
First check if any of the Lists is Empty (then you know the max and which list is providing it)
Integer max;
int list;
if (first.isEmpty()) {
max = Collections.max(second);
list = 2;
} else if (second.isEmpty()) {
max = Collections.max(first);
list = 1;
} else {
Integer max1 = Collections.max(first);
Integer max2 = Collections.max(second);
if (max1 > max2) {
max = max1;
list = 1;
} else {
max = max2;
list = 2;
}
}
System.out.println(list + " " + max);

Related

Permutation Iterator in java

I want a class, that take in a possitive integer and produce a iterator that let me iterate through all possible of permutation of a list of possitive numbers under the positive integer.
eg. permulator p = paermulator(3)
p.next() -> [0,1,2]
p.next() -> [0,2,1]
p.next() -> [1,0,2]
p.next() -> [1,2,0]
...
which is 6 possible permutations in this case.
I have designed a class, but it is incredibly slow, I want to make iterate faster.
This is my design:
(I am doing it pruely for that sake that it seems possible. )
package Mathematica.complexity;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Tthis will be a class that demonstrate what we call:
* a factorial complexity algorithm
* it's going to print all the possible permutations of some sort of collection
* in java.
* <br>
* A recursive data structure that resembles the process of permutating.
* #author dashie
*
*/
public class FactorialComplexity implements Iterator<List<Integer>>
{
private List<Integer> G_Data;
// sub recursive structure of the class.
private FactorialComplexity G_next = null;
private int G_ChoosenIndex = 0;
private boolean G_canProduceNextElement= true;
public static void main(String[] args)
{
}
public FactorialComplexity(int NumbersofElements)
{
if(NumbersofElements <0)throw new AssertionError();
this.G_Data = new LinkedList<>();
for(int i =0; i< NumbersofElements;i++)this.G_Data.add(i);
this.prepareSubStructure();
}
protected FactorialComplexity(List<Integer> argIn)
{
this.G_Data = argIn;
this.prepareSubStructure();
}
/**
* Using the internal index to return the current element it is
* pointing at.
* <br></b>I doesn't increment the internal pointer. </b>
* #return
*/
public Integer getChoosenElement()
{
//if(this.G_Data.size() == 0)return null;
return this.G_Data.get(this.G_ChoosenIndex);
}
/**
* This function serves for the iterator.
* #return
*/
public List<Integer> getPermutation()
{
// two of the base case.
if(this.G_Data.size()==0)
{
return new LinkedList<>();
}
if(this.G_Data.size()==1)
{
List<Integer> temp = new LinkedList<>();
temp.add(this.G_Data.get(0));
return temp;
}
return this.getPermutation_part1(new LinkedList<Integer>());
}
private List<Integer> getPermutation_part1(List<Integer> argIn)
{
argIn.add(getChoosenElement());
argIn.addAll(this.G_next.getPermutation());
return argIn;
}
/**
* <ol>
* <li>If the sub-structure has next element, increment the sub structure.
* <li>If not, increment the index in this instance and recreate sub structure.
* <li>be careful about the base case please.
* </ol>
*
* #return
* if this, including sub structure should be incremented.
*
*/
protected boolean increment()
{
if(this.G_next!= null)
{
boolean temp = this.G_next.increment();
int pointer = this.G_ChoosenIndex;
if(this.G_ChoosenIndex+1<this.G_Data.size())
{
if(temp)
{
this.G_ChoosenIndex++;
this.prepareSubStructure();
}
return false;
}
else
{
return (this.G_ChoosenIndex+1 == this.G_Data.size())&&temp;
}
}
else
{
//empty means not choice can make.
return true;
}
}
#Override
/**
* All the nodes are at its last index.
*/
public boolean hasNext()
{
if(!this.G_canProduceNextElement)return false;
if(this.isAllPointingAtLastIndex())this.G_canProduceNextElement=false;
return true;
}
/**
* This index in this class instance and
* all its sub structure are pointing at the last index?
* #return
*/
boolean isAllPointingAtLastIndex()
{
if(this.G_Data.size()<=1)
{
return true;
}
return this.G_ChoosenIndex+1
==
this.G_Data.size()&&this.G_next.isAllPointingAtLastIndex();
}
#Override
public List<Integer> next()
{
List<Integer> result = this.getPermutation();
this.increment();
return result;
}
public String toString()
{
String s = new String();
s+= this.G_Data+":"+this.G_ChoosenIndex+"->";
if(this.G_next!= null)s+= this.G_next.toString();
return s;
}
/**
* <ol>
* <li>Base case: the list in this instant is empty.
* <li>Make a copy of the local collection, excluding the
* element the pointer is pointing to
* <li>Make connect the this object to its sub structure and recurse.
* </ol>
*/
protected void prepareSubStructure()
{
if(this.G_Data.size() == 0)return;
List<Integer> temp = new LinkedList<>();
temp.addAll(this.G_Data);
temp.remove(this.G_ChoosenIndex);
this.G_next = new FactorialComplexity(temp);
this.G_next.prepareSubStructure();
}
public static int factorial(int n)
{
if(n<0)return 0;
if(n<=1)return 1;
return n*factorial(n-1);
}
}
To summarize:
The class is recursive like a linked list, each node contains the an index that indicate the element it is pointing at and a list of all the element got passed from the previouse node.
How Naive is this approach? How can I make it faster?
This is a better solution, inspired by https://stackoverflow.com/a/10117424/312172
To achieve, instead of getting a list of elements that are jumbled, we focus on the choices we make when deducting elements from the list.
give the function a size, and a number that is smaller than factorial(size); it will return a sequence of choices we need to make to get the permutation.
for example:
getTheIndexOfSelection(100,5)-> for a list of 5 elements, we want the 100th permutation.
it should output: [4, 0, 2, 0, 0]
it means, remove the element at index 4, for the list that got removed, remove element at 0 ....
if the list is[1,2,3,4,5]; this will be the procujure:
[1,2,3,4,5] remove index 4 -> 5
[1,2,3,4] remove index 0 -> 1
[2,3,4] remove index 2 -> 4
[2,3] rovmove index 0 -> 2
[3] remove index 0 -> 3
all the element we removed sequentially is the permutation.
/**
* Feed this function a number, it gives you a sequence of choices
* to make a permutation.
* <br>
* if this return [0,0,0,0]
* it means remove element at 0, and then remove again... until
* reaches the end.
* #return
*
* #param
* len: the length of the list
* n: the number that got match to a certain permutation.
*/
public static int[] getTheIndexOfSelection(int n, int size)
{
int[] lst = new int[size];
return getTheIndexOfSelection( n, size, 0, lst);
}
private static int[] getTheIndexOfSelection(int n, int size, int index, int[] lst)
{
if(size==1)
{
int[] result = {0}; // a list of one element, you can only choose the one that is in it
// which is at index 0;
return result;
}
if(n >= factorial(size))return null; // This is not possible to do.
size-=1;
int firstchoice = n/factorial(size);
lst[index] = firstchoice;
n = n-firstchoice*factorial(size);
if(size>1)return getTheIndexOfSelection(n ,size, index+1, lst);
return lst;
}
This is a better solution because:
The speed really depends on the factorial function, assume factorial is super fast, this will be o(n).
It matches numbers to permutation, making the expandable for things like map and iterator.
It is not the full solution, the part that is left to solve do is pretty much trivial by now.
An implementation using Heap's Algorithm. It compute next permutations on the fly. And have only one array copying
import java.util.Arrays;
import java.util.Iterator;
class Permutator<E> implements Iterator<E[]>{
E[] arr1 = null;
E[] arr2 = null;
int size;
int[] stack = null;
int index = 0;
public Permutator( E[] arr ){
if( arr.length > 0 ){
arr1 = arr;
size = arr1.length;
arr2 = Arrays.copyOf(arr1, size);
stack = new int[size];
Arrays.fill(stack, 0);
}
}
#Override
public boolean hasNext() {
return (null != arr1 && arr1.length > 0);
}
#Override
public E[] next() {
// start computing.
// We will return original array as value of last permutation.
// This is to make "hasNext() " implementation easy.
updateValue();
return arr2;
}
protected void updateValue(){
boolean bret = false;
for( ; index < size ; ){
if( stack[index] < index ){
if( index %2 == 0 ){
swap(0, index);
}else{
swap(stack[index], index);
}
stack[index]++;
index = 0;
bret = true;
break;
}else{
stack[index] = 0;
index++;
}
}
if( !bret ){
// No more permutation available.
// Set the original array as return value.
// Also set arr1 = null , so that hasNext() will return false for next test
arr2 = arr1;
arr1 = null;
}
}
private void swap (final int i, final int j) {
E temp = arr2[i];
arr2[i] = arr2 [j];
arr2[j] = temp;
}
}
Usage:
public static void main(String[] args) {
Permutator<Integer> perm = new Permutator<Integer>(new Integer[]{1,2,3, 4, 5});
int count = 0;
while(perm.hasNext()){
System.out.println(Arrays.toString(perm.next()));
count++;
}
System.out.println("total: " + count);
}

How would I convert this code to Generics?

I am in desperate need of help here. I am to migrate this existing code to generics and I've really hit a wall. Any help would be greatly appreciated.
The existing code is an algorithm library and is accompanied by some classes with constructors for vehicles (i.e Bike.Java).
I've tried alot of different things but I just can't seem to figure it out. I'd love some insight.
public class Algo
{
/**
* Copies all objects from src to tgt, for which the predicate pred holds.
*
* #param src source list
* #param tgt target list
* #param pred unary predicate
*/
static public
void copyIf(List src, List tgt, UnaryPredicate pred)
{
for (Object obj : src)
{
if (pred.test(obj)) tgt.add(obj);
}
}
/**
* Copies all objects from src to tgt that are greater than yardstick.
*
* #param src source
* #param tgt target
* #param yardstick determines if objects in src should be copied to tgt.
*/
static public
void copyIfGreaterThan(List src, List tgt, final Comparable yardstick)
{
copyIf(src, tgt, new UnaryPredicate() {
public boolean test(Object o)
{
return yardstick.compareTo(o) < 0;
}
});
}
/**
* Finds a maximum object in lst.
*
* #param lst a list containing non-null references
* #return a maximum object in lst
*/
static public
Comparable findMax(List lst)
{
assert lst != null;
Comparable max = null;
Iterator iter = lst.iterator();
// handle first element
if (iter.hasNext())
max = (Comparable) iter.next();
// handle remaining elements
while (iter.hasNext())
{
assert max != null;
Comparable cand = (Comparable) iter.next();
if (max.compareTo(cand) < 0)
max = cand;
}
return max;
}
/**
* Adds the smaller of lhs and rhs to dst.
*
* #param lhs left hand side object
* #param rhs right hand side object
* #param dst destination list
*/
static public
void storeMin(Comparable lhs, Comparable rhs, List dst)
{
Comparable min = lhs;
if (min.compareTo(rhs) > 0) min = rhs;
dst.add(min);
}
/**
* swaps the elements at a and b in lst.
*
* #param lst a list
* #param a first location in lst
* #param b second location in lst
*/
static private
void swap(ArrayList objs, int a, int b)
{
Object tmp = objs.get(a);
objs.set(a, objs.get(b));
objs.set(b, tmp);
}
/**
* Sorts the elements in lst.
*
* #param lst an array list containing non-null references
*/
static public
void selectionSort(ArrayList lst)
{
for (int i = 0; i < lst.size(); ++i)
{
int min = i;
Comparable minobj = (Comparable) lst.get(min);
for (int j = i+1; j < lst.size(); ++j)
{
if (minobj.compareTo(lst.get(j)) > 0)
{
min = j;
minobj = (Comparable) lst.get(min);
}
}
swap(lst, min, i);
}
}
}
Since Java 8 you could do it like that:
public static <T> List<T> copyIf(List<T> src, Predicate<T> predicate){
return src.stream().filter(predicate).collect(Collectors.toList());
}
public static <T> List<T> copyIfGreaterThan(List<T> src, Comparable<T> yardstick) {
return copyIf(src, t -> (yardstick.compareTo(t) < 0));
}
For more infos about generics see:
https://docs.oracle.com/javase/tutorial/java/generics/types.html
For more infos on streams see e.g.
https://www.tutorialspoint.com/java8/java8_streams.htm

Quicksort array is not printing out correctly? (java)

I'm currently working on a university assignment which involves implementing sorting algorithms. I believe I have correctly implemented the quicksort algorithm, however in the test class the method just prints out the array being read in without sorting it. Below is the code from the test class, and the code for the actual quicksort(which is in a seperate class called 'sort').
Has anyone got any idea what I'm doing wrong?
import java.io.*;
import java.text.*;
import java.util.*;
public class Sort {
/** Array of integers to sort **/
private int[] A;
/** Size of the array **/
private int size;
/** Number of elements actually used in array **/
private int usedSize;
/** Global variables for counting sort comparisons **/
public int compIS;
/** Global comparison count for Insertion Sort **/
public int compQS;
/** Global comparison count for Quicksort **/
public int compNewS;
/** Global comparison count for new sort **/
/*****************/
/** Constructor **/
/*****************/
Sort(int max) {
/** Initialiase global sort count variables **/
compIS = 0;
compQS = 0;
compNewS = 0;
/** Initialise size variables **/
usedSize = 0;
size = max;
/** Create Array of Integers **/
A = new int[size];
}
public int getRightElement() {
return usedSize - 1;
}
public int getLeftElement() {
return A[0];
}
/*********************************************/
/*** Read a file of integers into an array ***/
/*********************************************/
public void readIn(String file) {
try {
/** Initialise loop variable **/
usedSize = 0;
/** Set up file for reading **/
FileReader reader = new FileReader(file);
Scanner in = new Scanner(reader);
/** Loop round reading in data while array not full **/
while (in.hasNextInt() && (usedSize < size)) {
A[usedSize] = in.nextInt();
usedSize++;
}
} catch (IOException e) {
System.out.println("Error processing file " + file);
}
}
/**********************/
/*** Display array ***/
/**********************/
public void display(int line, String header) {
/*** Integer Formatter - three digits ***/
NumberFormat FI = NumberFormat.getInstance();
FI.setMinimumIntegerDigits(3);
/** Print header string **/
System.out.print("\n" + header);
/** Display array data **/
for (int i = 0; i < usedSize; i++) {
/** Check if new line is needed **/
if (i % line == 0) {
System.out.println();
}
/**
* Display an ar ray element
**/
System.out.print(FI.format(A[i]) + " ");
}
}
public void quick(int L, int R) {
/* ensure there is more than one element in array */
if (R > L) {
/* split array in two */
int pLoc = partition(L, R);
/* sort left half */
quick(L, pLoc - 1);
/* sort right half */
quick(pLoc + 1, R);
}
System.out.println("\n\nAfter QuickSort: ");
for (int i = 0; i < usedSize; i++) {
System.out.println(A[i] + " ");
}
}
/* partitions array for quicksort */
public int partition(int L, int R) {
/* Select pivot */
int pivot = A[R];
/* initialise scanning pointers */
int pR = R;
int pL = L;
/* repeat until pointers cross */
while (pL < pR) {
compQS++;
/* move left pointer */
while (A[pL] < pivot) {
pL++;
}
/* move right pointer */
while ((A[pR] >= pivot) && (pR > L)) {
pR--;
//compQS++;
}
/* swap elements */
//compQS++;
if (pL < pR) {
swap(pL, pR);
L++;
R--;
}
}
/* put pivot in correct position */
swap(pL, R);
/* return pivot position */
return pL;
}
/* swaps elements in quicksort */
public void swap(int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
public class TestSort
{
public static void main(String[] args)
{
Sort sortTest = new Sort(100);
/** Read in test data into array **/
sortTest.readIn("test1.txt");
/** Display array **/
sortTest.display(10,"Input Array 1");
/*apply insertion sort to array*/
//sortTest.insertion();
//sortTest.readIn("test1.txt");
sortTest.quick(sortTest.getLeftElement(), sortTest.getRightElement());
sortTest.newSort();
/** Display comparison counters **/
System.out.println("Quicksort comparison counter: " + sortTest.compQS);
System.out.println("\n\nInsertion sort comparison counter: " + sortTest.compIS);
}
One of your problems is that getLeftElement() is returning the value at position 0 within your array instead of just returning 0. In situations in which the value of the first element in the array is greater than the size of the array, no sorting will be done.
Also, I believe that your implementation of the method quick is incorrect. Within the method you recursively invoke quick(L, pLoc - 1)
and quick(pLoc + 1, R). By invoking in this manner, you do not traverse all indices of the array in your array. (Ex if L is 0, R is 10, and pLoc is 5, then you do not involve the index 5 in the sorting of your array.)

NullPointerException when accessing array elements

I'm using BlueJ to create an array. The array is of 10 objects inherited from another class.
Now, my problem is that every time I try to find an object within the array (using the findInventoryItem, I get a java.lang.NullPointerException: null error. Now the "inventoryItem" object comes from another class. I am using inventoryItems as the actual array name. the objects that go into it are the inventoryItem of class InventoryItem
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
/**
* THIS IS THE MODIFIED VERSION OF THE ARRAY LIST MANAGER CLASS
*
* #author RAGEED A BASRAWI
* #version VERSION 1
*/
public class HomeInventoryManagerARRAYClass
{
private InventoryItem inventoryItem;
private InventoryItem[] inventoryItems;
/**
* Initialise the home inventory manager.
*/
public HomeInventoryManagerARRAYClass()
{
InventoryItem inventoryItem;
inventoryItems = new InventoryItem[10];
}
/**
* Add an inventory item to the list.
*
*/
public void addInventoryItem(InventoryItem inventoryItem)
{
Random random = new Random();
inventoryItems[random.nextInt(9 - 0 + 1) + 0] = inventoryItem;
}
/**
* Try to find an inventory item in the inventory list with the given partNumber.
*
*/
public InventoryItem findInventoryItem(int partNumber)
{
for(int index = 0; index < 9; index ++)
{
if (inventoryItem.getPartNumber() == partNumber)
{
return inventoryItem;
}
if (inventoryItem.getPartNumber() != partNumber)
{
System.out.println("The entry " + partNumber + " does not exist. Pleast try again.");
}
}
return inventoryItem;
}
/**
* Locate an inventory item with the given partNumber, and return how
* many of this item are in inventory. If the partNumber does not
* match any item, return zero.
*/
public int numberInInventory(int partNumber)
{
InventoryItem inventoryItems = findInventoryItem(partNumber);
if(inventoryItems != null)//There aren't too many ways to write a statement to be NOT NULL. Its kind of annoying... -___-
{
return inventoryItems.getQuantity();
}
else
{
return 0;
}
}
/**
* Return the total number of items in inventory.
*
*/
public int numberInInventoryList()
{
return inventoryItems.length;
}
/**
* Print details of all the home inventory items.
*/
public void printInventoryList()
{
int index = 0;
while(index < inventoryItems.length)
{
System.out.println(inventoryItem = inventoryItems[index]);
index ++;
}
}
public int totalNumberInInventory()
{
int index = 0;
int absoluteInventory = 0;
while (index < inventoryItems.length)
{
InventoryItem inventoryItem = inventoryItems[index];
absoluteInventory += inventoryItem.getQuantity();
index ++;
}
return absoluteInventory;
}
}
inventoryItems[random.nextInt(9 - 0 + 1) + 0] = inventoryItem;
if you initialize the array with the line above, how do you make sure that all elements of the array are initialized? It's generating a random number and doesn't guarantee all elements between 0 to 9 are initialized.
Remember that with this line:
inventoryItems = new InventoryItem[10];
you are initializing your array, not its elements. When running functions again each array's element you should be sure that you have initialized the element itself.
For example :
InventoryItem[i].getPartNumber()
this line of code should be executed before
InventoryItem[i] = new InventoryItem();
As #Jahoy has mentioned, it's likely that the elements in the array that you are accesing are null. It is essential firstly to check if an element exists in the first place.
Your FindInventoryItem function should be like this I think:
public InventoryItem findInventoryItem(int partNumber)
{
for(int index = 0; index < 9; index ++)
{
InventoryItem tempItem = inventoryItems[index]; // ADD THIS LINE HERE
if(tempItem != null)
{
if (tempItem.getPartNumber() == partNumber)
{
return tempItem;
}
if (tempItem.getPartNumber() != partNumber)
{
System.out.println("The entry " + partNumber + " does not exist. Please try again.");
}
}
}
// at this stage you've got no result, I dont really know what you want to return
return inventoryItem;
}

Big theta notation for array and linked list classes [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am trying to determine the complexity metrics (Big-theta notation) for each method and constructor in my classes that create a queue using an array and a linked list as the underlying structures. Specifically, I am not sure how to look at and quickly determine whether each method or constructor is O(k) or O(n). Could someone explain this?
Array class:
public class UnboundedQueueArray<T> implements UnboundedQueue<T> {
// elements stored in array
private T[] elements;
// the number of elements currently in the queue
private int numElems;
// initial length of queue
private static final int INITIAL_LENGTH = 10;
/**
* Constructs the UnboundedQueueArray object.
*/
#SuppressWarnings("unchecked")
public UnboundedQueueArray() {
elements = (T[]) new Object[INITIAL_LENGTH];
numElems = 0;
}
/**
* This method inserts the specified element, unless the
* queue is full.
*
* #param o The element to be inserted.
*/
public void insert(T o) {
// checks and enlarges capacity if necessary
ensureExtraCapacity(1);
elements[numElems] = o;
numElems++;
}
// this helper method ensures there is always extra capacity
// in the queue to insert elements
#SuppressWarnings("unchecked")
private void ensureExtraCapacity(int extraCapacity) {
if(numElems + extraCapacity > elements.length) {
// double old capacity
int newCapacity = elements.length * 2 + extraCapacity;
// allocate new array
T[] newElements = (T[]) new Object[newCapacity];
// copy contents of old array into new array
for(int i = 0; i < length(); i++) {
newElements[i] = elements[i];
}
// replace old array with new array
elements = newElements;
}
}
/**
* This method returns the element at the front of the
* queue, unless the queue is empty.
*
* #return The element at the front of the queue.
* #throws EmptyQueueException If the queue is empty.
*/
public T front() throws EmptyQueueException {
if(length() == 0) {
throw new EmptyQueueException("Queue is empty.");
}
return elements[0];
}
/**
* This method retrieves and removes the element at the front
* of the queue, unless the queue is empty.
*
* #return The element at the front of the queue.
* #throws EmptyQueueException If the queue is empty.
*/
public T remove() throws EmptyQueueException {
if(length() == 0) {
throw new EmptyQueueException("Queue is empty.");
}
// retrieve element at front of queue
T frontElem = elements[0];
// shift elements to the left
for(int i = 1; i < length(); i++) {
elements[i - 1] = elements[i];
}
// "null out" last element
elements[numElems - 1] = null;
// decrement number of elements
numElems--;
return frontElem;
}
/**
* This method reports whether or not the queue contains
* element(s).
*
* #return If one or more elements exists or not.
*/
public boolean hasMember() {
return (length() > 0);
}
/**
* This method returns the current length of the queue.
*
* #return The length of the queue.
*/
public int length() {
return numElems;
}
/**
* This method provides a string representation of the queue.
*
* #return The String representation of the queue.
*/
public String toString() {
// for empty queue
if(length() == 0) {
String str = "[ " + length() + " : ]";
return str;
}
// fencepost algorithm
String str = "[ " + length() + " : " + elements[0];
for(int i = 1; i < length(); i++) {
str += ", " + elements[i];
}
str += " ]";
return str;
}
}
Linked list class:
public class UnboundedQueueLinkedList<T> implements UnboundedQueue<T> {
// the reference to the first link
private Link first;
// the reference to the last link (if it exists)
private Link last;
// the number of links in the queue
private int numLinks;
// initial length of queue
private static final int INITIAL_LENGTH = 10;
/**
* Constructs the UnboundedQueueLinkedList object.
*/
#SuppressWarnings("unchecked")
public UnboundedQueueLinkedList() {
first = null;
last = null;
numLinks = 0;
}
/**
* This method inserts the specified element, unless the
* queue is full.
*
* #param o The element to be inserted.
*/
public void insert(T o) {
Link newLink = new Link(o, null);
if(first == null) {
// we are adding the first link
first = newLink;
} else { // there are existing links, so add newLink after old last link
last.next = newLink;
}
// update the last link
last = newLink;
// increment the number of links in the queue
numLinks++;
}
/**
* This method returns the element at the front of the
* queue, unless the queue is empty.
*
* #return The element at the front of the queue.
* #throws EmptyQueueException If the queue is empty.
*/
#SuppressWarnings("unchecked")
public T front() throws EmptyQueueException {
if(length() == 0) {
throw new EmptyQueueException("Queue is empty.");
}
T frontElem;
// get link at front of queue
Link frontLink = getLinkAtPos(0);
frontElem = (T) frontLink.item;
return frontElem;
}
// this helper method gets the link at the specified position
private Link getLinkAtPos(int pos) {
Link p = first;
for(int i = 0; i < pos; i++) {
p = p.next;
}
return p;
}
/**
* This method retrieves and removes the element at the front
* of the queue, unless the queue is empty.
*
* #return The element at the front of the queue.
* #throws EmptyQueueException If the queue is empty.
*/
#SuppressWarnings("unchecked")
public T remove() throws EmptyQueueException {
if(length() == 0) {
throw new EmptyQueueException("Queue is empty.");
}
T removedElem;
removedElem = (T) first.item;
// remove "first" link
first = first.next;
// update "last" if necessary
if(first == null) {
last = null;
}
// decrement the number of links in the queue
numLinks--;
return removedElem;
}
/**
* This method reports whether or not the queue contains
* element(s).
*
* #return If one or more elements exists or not.
*/
public boolean hasMember() {
return (length() > 0);
}
/**
* This method returns the current length of the queue.
*
* #return The length of the queue.
*/
public int length() {
return numLinks;
}
/**
* This method provides a string representation of the queue.
*
* #return The String representation of the queue.
*/
public String toString() {
// for empty queue
if(length() == 0) {
String str = "[ " + length() + " : ]";
return str;
}
Link p = first;
String str = "[ " + length() + " : " + p.item;
for(int i = 1; i < numLinks; i++) {
p = p.next;
str += ", " + p.item;
}
str += " ]";
return str;
}
// this helper class creates the links that structure the list
class Link<T> {
// data associated with this link
public Object item;
// next link, or null if no next link
public Link next;
/**
* Constructs the Link object.
*
* #param item The data to be associated with this Link object.
* #param next The next link (or null if no next link exists).
*/
public Link(Object item, Link next) {
this.item = item;
this.next = next;
}
}
}
EDIT: Here is stack array class:
public class UnboundedStackArray<T> implements UnboundedStack<T> {
// elements stored in array
private T[] elements;
// the number of elements currently in the stack
private int numElems;
// initial depth of stack
private static final int INITIAL_DEPTH = 10;
/**
* Constructs the UnboundedStackArray object.
*/
#SuppressWarnings("unchecked")
public UnboundedStackArray() {
elements = (T[]) new Object[INITIAL_DEPTH];
numElems = 0;
}
/**
* This method "pushes" an element onto the top of the stack.
*
* #param o The element to be "pushed" (or added) onto the top
* of the stack.
*/
public void push(T o) {
// ensure space to add element
ensureExtraCapacity(1);
elements[numElems] = o;
// increment the number of elements in the stack
numElems++;
}
// this helper method ensures there is always extra capacity
// in the stack to "push" (or add) elements onto top of stack
#SuppressWarnings("unchecked")
private void ensureExtraCapacity(int extraCapacity) {
if(numElems + extraCapacity > elements.length) {
// double old capacity
int newCapacity = elements.length * 2 + extraCapacity;
// allocate new array
T[] newElements = (T[]) new Object[newCapacity];
// copy contents of old array into new array
for(int i = 0; i < depth(); i++) {
newElements[i] = elements[i];
}
// replace old array with new array
elements = newElements;
}
}
/**
* This method retrieves the element at the top of the stack,
* unless the stack is empty.
*
* #return The element at the top of the stack.
* #throws EmptyStackException If the stack is empty.
*/
public T top() throws EmptyStackException {
if(depth() == 0) {
throw new EmptyStackException("Stack is empty");
}
return elements[numElems - 1];
}
/**
* This method retrieves and removes the element at the top of
* the stack, unless the stack is empty.
*
* #return The element at the top of the stack.
* #throws EmptyStackException If the stack is empty.
*/
public T pop() throws EmptyStackException {
if(depth() == 0) {
throw new EmptyStackException("Stack is empty");
}
// retrieve element at top of stack
T topElem = elements[numElems - 1];
// "null out" element at top of stack
elements[numElems - 1] = null;
// decrement number of elements
numElems--;
return topElem;
}
/**
* This method reports whether or not the stack contains
* element(s).
*
* #return If one or more elements exists or not.
*/
public boolean hasMember() {
return (depth() > 0);
}
/**
* This method returns the current depth (or length) of the stack.
*
* #return The depth of the stack.
*/
public int depth() {
return numElems;
}
/**
* This method provides a string representation of the stack.
*
* #return The String representation of the stack.
*/
public String toString() {
// for empty stack
if(depth() == 0) {
String str = "[ " + depth() + " : ]";
return str;
}
String str = "[ " + depth() + " : " + elements[numElems - 1];
for(int i = numElems - 2; i >= 0; i--) {
str += ", " + elements[i];
}
str += " ]";
return str;
}
}
Here is stack linked list class:
public class UnboundedStackLinkedList<T> implements UnboundedStack<T> {
// the reference to the first link
private Link first;
// the reference to the last link (if it exists)
private Link last;
// the number of links in the stack
private int numLinks;
// initial length of stack
private static final int INITIAL_LENGTH = 10;
/**
* Constructs the UnboundedStackLinkedList object.
*/
#SuppressWarnings("unchecked")
public UnboundedStackLinkedList() {
first = null;
last = null;
numLinks = 0;
}
/**
* This method "pushes" an element onto the top of the stack.
*
* #param o The element to be "pushed" (or added) onto the top
* of the stack.
*/
public void push(T o) {
Link newLink = new Link(o, null);
if(first == null) {
// add the first link
first = newLink;
} else { // there are existing links, so add newLink after old last link
last.next = newLink;
}
// update the last link
last = newLink;
// increment the number of links in the queue
numLinks++;
}
/**
* This method retrieves the element at the top of the stack,
* unless the stack is empty.
*
* #return The element at the top of the stack.
* #throws EmptyStackException If the stack is empty.
*/
#SuppressWarnings("unchecked")
public T top() throws EmptyStackException {
if(depth() == 0) {
throw new EmptyStackException("Stack is empty.");
}
T topElem;
// get link at front of queue
Link topLink = getLinkAtPos(numLinks - 1);
topElem = (T) topLink.item;
return topElem;
}
// this helper method gets the link at the specified position
private Link getLinkAtPos(int pos) {
Link p = first;
for(int i = 0; i < pos; i++) {
p = p.next;
}
return p;
}
/**
* This method retrieves and removes the element at the top of
* the stack, unless the stack is empty.
*
* #return The element at the top of the stack.
* #throws EmptyStackException If the stack is empty.
*/
#SuppressWarnings("unchecked")
public T pop() throws EmptyStackException {
if(depth() == 0) {
throw new EmptyStackException("Stack is empty.");
}
T removedElem;
removedElem = (T) last.item;
Link p = first;
for(int i = 0; i < depth() - 2; i++) {
p = p.next;
}
//p.next = null;
last = p;
// update "last" if necessary
if(first == null) {
last = null;
}
// decrement the number of links in the queue
numLinks--;
return removedElem;
}
/**
* This method reports whether or not the stack contains
* element(s).
*
* #return If one or more elements exists or not.
*/
public boolean hasMember() {
return (depth() > 0);
}
/**
* This method returns the current depth (or length) of the stack.
*
* #return The depth of the stack.
*/
public int depth() {
return numLinks;
}
/**
* This method provides a string representation of the stack.
*
* #return The String representation of the stack.
*/
#SuppressWarnings("unchecked")
public String toString() {
// for empty stack
if(depth() == 0) {
String str = "[ " + depth() + " : ]";
return str;
}
Link pL = last;
String str = "[ " + depth() + " : " + pL.item;
for(int i = numLinks - 2; i >= 0; i--) {
Link tempLink = getLinkAtPos(i);
str += ", " + tempLink.item;
}
str += " ]";
return str;
}
// this helper class creates the links that structure the list
class Link<T> {
/**
* Data associated with this link.
*/
public Object item;
/**
* Next link, or null if no next link.
*/
public Link next;
/**
* Constructs the Link object.
*
* #param item The data to be associated with this Link object.
* #param next The next link (or null if no next link exists).
*/
public Link(Object item, Link next) {
this.item = item;
this.next = next;
}
}
}
Array class:
UnboundedQueueArray: O(1)
insert: O(1)
ensureExtraCapacity: O(n) (n = current length)
"O(n) is worst case, O(1) otherwise"
front: O(1)
remove: O(n)
"Always O(n)"
length: O(1)
Optimalization:
I highly recommend you use a stack for this behavior, since it handles each method with O(1) complexity.
Linked list:
UnboundedQueueLinkedList: O(1)
insert: O(1)
The behavior seems to be incorrect
last.next = newLink;
last = newLink;
getLinkAtPos: O(pos)
remove: O(1)
length: O(1)
There are some optimalizations that can be done.
UnboundedQueueLinkedList.getLinkAtPos
If you make this a double-linked list, then you could start at the end if pos > length() / 2. This will reduce worst-case complexity to O(log(n)).
Stack array class:
UnboundedStackArray: O(1)
push: O(1) + ensureExtraCapacity
ensureExtraCapacity: wcs is O(n), bcs is O(1)
top: O(1)
pop: O(1)
depth: O(1)
toString: O(n)
I would definitely not use an array for a stack, a list is much more efficient
Stack linked list:
UnboundedStackLinkedList: O(1)
push: O(1)
Again, it looks like the functionality is incorrect
top: O(1) + getLinkAtPos
getLinkAtPos: O(n)
pop: O(n)
depth: O(1)
toString: O($n^2$)
This could be much more efficient.
If you create a stack, you only have to keep track of the top item. Each time you push, the top item gets replaced by the new item and the next linked item of the new item is the old top.
Each time you pop, the top item gets popped and its reference it set as the new top. The only method that would be more than O(1) would be the toString() method.
#user2581779: I'll try to explain what O(n) means, but I will not examine your code. Hopefully, you will be able to answer this (and other related questions) after reading my answer by yourself.
Why Big-O notation?
First of all, you should understand why O-notation is used. You could for example use seconds of execution time on a given computer, right?
Well, this has a lot of problems:
Even if every programmer / computer scientist had the same computer for executing, the time would vary (because of many factors, e.g. temperature)
You would have to thing very carefully about your test cases. Let's say you want to examine an algorithm that sorts elements in an array. What do you want to sort (numbers / objects)? How many objects do you want to sort? This might influence the time you measure
You only get statements for the concrete architecture / system you've tested.
Okay, simply measuring seconds is not a good idea. But why don't you measure number of operations?
The number of operations might be difficult to determine (How many operations are int a = 7 + 3? How many are a += b? You have to think about compiler optimizations and how the underling assembler would look)
In theory, you're always more interested in how your algorithm develops when you increase the input size.
So, suppose you have an array of n elements. You want to get these elements sorted. Algorithm A needs n^2 + 1234 operations, algorithm B nees n^1.9 + 123123123123123 operations. Which one is better? (Please note that n is only a variable. I could also name it k or whatever)
Quite long, algorithm A will perform better. But as soon as B gets better (with more elements n) it will be MUCH better than A.
So, you can forget about additive constant terms. And also about multiplicative constants. In practice, multiplicative constants might be very important, but Big-O notation skips that out.
Please note that you care about worst cases. Best cases are equally easy to examine, but not interesting.
Average case analysis is difficult to get done right. If you want to try it, search for "accounting method" or "aggregation method".
For what is Big-O notation used?
Space- and time complexity. For most simple applications, only time complexity is important. But please note that you can quite often make a time/space trade-off. When you store more information, your algorithm might be faster.
Big-O notation is only used to get a feeling for how strong a function is growing.
Mathematics
Formally:
Let g : N -> R be a function.
O(g(n)) &:= {f(n) | \exists_{c > 0} \exists_{n_0 > 0} \forall_{n \geq n_0}: f(n) < c *g(n) }
(See my site for a rendered version)
This means, when it is correct to say that your program is in O(n), it is also correct to say it is in O(n^2). Big Theta notation makes this better, but is much more difficult to determine correctly.
How do I get Big-O notation?
For most programs, its quite simple:
First of all, define the value that is growing (e.g. number of elements you want to sort). This is your n.
Then take a look at loops.
One loop over n means you're at lest in O(n) (it might be worse, though)
A nested loop where both variables loop from 0..n means your in O(n^2) or worse
Take a look at recursive functions. Examine it with Master theorem.
Take a look at datastructures and functions you call. For many Java datastructures, you can get the big-O time complexity by searching
Tree-datastructures often have something with log(n) when the tree is balanced, as this is the height of the tree (but only if you can guarantee that it is balanced!)
You can get the time by analyzing sums. So when you have two nested loops, one from 0..n with running variable i and one from i..n which does one "basic" operation you get sum_{i=0}^n \sum_{j=i}^n 1 = sum_{i=0}^n i = (n^2 + n)/2 + 1. It needs a little bit of practice to determine which operations are 1 and which are n or something different, but as soon as you have written them in a mathematical way, you can use Wolfram|Alpha to simplify them. See my article about Gaussian elimination for an example.
Specifically, I am not sure how to look at and quickly determine whether each method or constructor is O(k) or O(n).
First, go through the code and find all the methods that contain only O(1) code. These methods won't have loops that run n times, and won't call O(n) methods. Since these just run straight through, they are O(1), even if they call many other O(1) methods outside of loops. If the method loops through O(0) code n times, that method is 0(n). If it has multiple O(n) operations that are not inside loops, it's still O(n), though potentially with a larger coefficient of n. If it has O(n) code that is performed n times, it's O(n^2).
Array
UnboundedQueueArray() is O(INITIAL_LENGTH), which is O(1) since INITIAL_LENGTH is constant. ensureExtraCapacity(int extraCapacity) is O(n) whenever it extends the internal array since it declares an array of size newCapacity (which must be greater than n) and runs a loop n times, but is O(1) otherwise.
insert is where things get fun. Roughly every n times it is called, it calls ensureExtraCapacity as an O(n) operation. If you do something O(n) once every n times you are called, you are O(n/n) on average, or O(1). But since you are occasionally O(n), we give this a special name: amortized constant time.
front, hasMember, and length are O(1), remove is O(n) because of the loop, and toString is only O(n) since we can access elements in constant time.
LinkedList
UnboundedQueueLinkedList (the constructor), insert, front, remove, hasMember, and length are all O(1). getLinkAtPos(int pos) could be said to be O(pos), but we just call it O(n) since the worst case gets bigger as n gets bigger.
toString() is O(n^2), because it performs an O(n) operation, getLinkAtPos, n times.
Notes:
If you go back to your original implementation of toString() for the LinkedList, you can get it to go down to O(n) since you avoid calling getLinkAtPos inside the loop.
public String toString() {
// for empty queue
if(length() == 0) {
String str = "[ " + length() + " : ]";
return str;
}
Link p = first;
String str = "[ " + length() + " : " + p.item;
for(int i = 1; i < numLinks; i++) {
p = p.next;
str += ", " + p.item;
}
str += " ]";
return str;
}

Categories