│ │
│ │
│ │
├─────────┤
│ D │ ← top
├─────────┤
│ C │
├─────────┤
│ B │
├─────────┤
│ A │
└─────────┘
│ ↓ │
├─────────┤
│ E │ ← top
├─────────┤
│ D │
├─────────┤
│ C │
├─────────┤
│ B │
├─────────┤
│ A │
└─────────┘
push(E)
│ F │ ← top
├─────────┤
│ E │
├─────────┤
│ D │
├─────────┤
│ C │
├─────────┤
│ B │
├─────────┤
│ A │
└─────────┘
push(F)
│ │
├─────────┤
│ E │ ← top
├─────────┤
│ D │
├─────────┤
│ C │
├─────────┤
│ B │
├─────────┤
│ A │
└─────────┘
pop() → returns F
returns top and updates it (removes top)
│ │
│ │
│ │
├─────────┤
│ D │ ← top
├─────────┤
│ C │
├─────────┤
│ B │
├─────────┤
│ A │
└─────────┘
pop() → returns E returns top and updates it (removes top)
push() and pop(), others?Write up a generic stack interface
public interface Stack<T> {
/**
* Stack is LIFO – Last In, First Ou
* add a new value (with T data) to the top of the stack
* @param data of generic type T
*/
void push(T data);
/**
* Removes and returns the value at the top of the stack
* @return the value stored in the node at the top of the stack
*/
T pop();
/**
* Looks at the value at the top of the stack without removing it
* @return the value stored in the node at the top of the stack
*/
T top();
/**
* @return true if Stack is empty, false otherwise
*/
boolean isEmpty();
}Submit your Stack.java, ArrayStack.java and LinkedStack.java to gradescope
public class ArrayStack<T> implements Stack<T>{
private T[] stack;
private int count;
public ArrayStack(int size) {
stack = (T[]) new Object[size];
count = 0;
}
@Override
public void push(T data) {
stack[count] = data;
count++; // what happens when count is equal or greater than size?
}
@Override
public T pop() {
if (count == 0) return null;
count--;
return stack[count];
}
@Override
public T top() {
if (count == 0) return null;
return stack[count-1];
}
@Override
public boolean isEmpty() {
return count == 0;
}
@Override
public String toString() {
String out = "";
for (int i=count-1; i >= 0; i--)
out += "| " + stack[i] + "\t|\n";
return out;
}
}
public class LinkedStack<T> implements Stack<T>{
private Node<T> top;
public LinkedStack() {
top = null;
}
@Override
public void push(T data) {
Node<T> newTop = new Node<>(data);
newTop.setNext(top);
if (!isEmpty()) top.setNext(top.getNext());
top = newTop;
}
@Override
public T pop() {
if (!isEmpty()) {
T out = top.getData();
top = top.getNext();
return out;
}
return null;
}
@Override
public T top() {
if (!isEmpty()) return top.getData();
return null;
}
@Override
public boolean isEmpty() {
return top == null;
}
@Override
public String toString() {
String out = "";
Node<T> currNode = top;
while (currNode != null) {
out += "| " + currNode.getData() + "\t|\n";
currNode = currNode.getNext();
}
return out;
}
}First In First Out
back ┌───┬───┬───┬───┐ front
─────▶│ D │ C │ B │ A │──────▶
└───┴───┴───┴───┘
enqueue(E)
adds to back
back ┌───┬───┬───┬───┬───┐ front
─────▶│ E │ D │ C │ B │ A │──────▶
└───┴───┴───┴───┴───┘
dequeue()
removes from front
back ┌───┬───┬───┬───┐ front returns A
─────▶│ D │ C │ B │ A │──────▶
└───┴───┴───┴───┘
│
▼ after dequeue
back ┌───┬───┬───┐ front
─────▶│ D │ C │ B │──────▶
└───┴───┴───┘
peek()
returns front, no removal
back ┌───┬───┬───┬───┐ front
─────▶│ D │ C │ B │ A │──────▶
└───┴───┴───┴───┘
returns A
does NOT
remove it
enqueue() (adds to the end of the queue)dequeue() (removes from the beginning of the queue)Write up a generic queue interface
public interface Queue<T> {
/**
* Queue is First In, First Out
* @param data is the value to be added to the end of the queue
*/
void enqueue(T data);
/**
* Removes the value from the beginning of the queue and returns it
* @return the value of type T at the beginning of the queue
*/
T dequeue();
/**
* @return true if Queue is empty, false otherwise
*/
boolean isEmpty();
}Queue as a linked list vs. array implementation
head and tail like we did for our first Linked List implementation% operator to “wrap” around the array
count = array.lengthResizing?
0 1 2 3 4
┌───┬───┬───┬───┬───┐
│ │ │ A │ B │ │
└───┴───┴───┴───┴───┘
front index: 2
back index: 3
0 1 2 3 4
┌───┬───┬───┬───┬───┐
│ │ │ A │ B │ C │
└───┴───┴───┴───┴───┘
front index: 2
back index: 4
0 1 2 3 4
┌───┬───┬───┬───┬───┐
│ D │ │ A │ B │ C │
└───┴───┴───┴───┴───┘
front index: 2
back index: 0
0 1 2 3 4
┌───┬───┬───┬───┬───┐
│ D │ │ │ B │ C │
└───┴───┴───┴───┴───┘
front index: 3
back index: 0
0 1 2 3 4
┌───┬───┬───┬───┬───┐
│ D │ E │ │ B │ C │
└───┴───┴───┴───┴───┘
front index: 3
back index: 1
Submit your Array.java and ArrayQueue.java files to gradescope
Problem: this is not dealing with what happens when count = array.length
public class ArrayQueue<T> implements Queue<T>{
private T[] queue;
private int count;
private int front;
private int rear;
private int size;
public ArrayQueue(int size) {
queue = (T[]) new Object[size];
count = 0;
front = 0;
rear = 0;
this.size = size;
}
@Override
public T dequeue() {
T out = queue[front];
queue[front] = null;
front = (front + 1) % size;
count--;
return out;
}
@Override
public void enqueue(T data) {
queue[rear] = data;
count++;
rear = (rear + 1) % size;
}
@Override
public boolean isEmpty() {
return count == 0;
}
@Override
public String toString() {
String out = "";
for (int i=front;i<front+count;i++) {
if (queue[i%size] != null) out += i%size + " - " + queue[i%size] + " ";
}
return out.trim();
}
}