Trần Thị Thanh Nga
Khoa Công nghệ thông tin, ĐH Nông Lâm HCM
Stacks
Stacks
A stack is a container of objects that are inserted and
removed according to the Last-In-First-Out (LIFO)
principle.
Objects can be inserted at any time, but only the last
(the most-recently inserted) object can be removed.
Inserting an item is known as “pushing” onto the
stack. “Popping” off the stack is synonymous with
removing an item.
Stacks
Stacks examples
Example 5.1: Internet Web browsers store the addresses
of recently visited sites on a stack.
Each time a user visits a new site, that site's address is
"pushed" onto the stack of addresses.
The browser then allows the user to "pop" back to
previously visited sites using the "back" button.
Example 5.2: Text editors usually provide an "undo"
mechanism that cancels recent editing operations and
reverts to former states ofa document.
This undo operation can be accomplished by keeping
text changes in a stack.
Stacks
The Stack Abstract Data Type
A stack is an abstract data type (ADT) that supports
two main methods:
push(o): Inserts object o onto top of stack
Input: Object;
Output: none
pop(): Removes the top object of stack and returns it; if
stack is empty an error occurs
Input: none;
Output: Object
Stacks
The Stack Abstract Data Type
There are other methods:
size(): Return the number of elements in the stack.
Input: none; Output: integer;
isEmpty(): Return a Boolean indicating if the stack is
empty.
Input: none; Output: boolean;
top(): Return the top element in the stack, without removing
it; an error occurs if the stack is empty.
Input: none; Output: Object;
clear(): Remove all items from the stack.
Stacks
Stack example
Stacks
A Stack Interface in Java
Because of its importance, the stack data structure is
included as a "built-in" class in the java.util package of
Java. But you can define it your own specific one.
Implementing an abstract data type in Java involves two
steps.
the definition of a Java interface, which describes the names
of the methods that the ADT supports
how they are to be declared and used.
Stacks
A Stack Interface in Java
In addition, we must define exceptions for any error
conditions that can arise.
For example: the error condition that occurs when calling
method pop() or top() on an empty stack throwing an
exception of type EmptyStackException
public class EmptyStackException extends RuntimeException {
public EmptyStackException(String err) {
super(err);
}
}
Stacks
A Stack Interface in Java
public interface StackInterface<E> {
public int size();
public boolean isEmpty();
public E top() throws StackException;
public void push(E element);
public E pop() throws StackException;
public void clear();
}
Stacks
A Simple Array-Based Stack Implementation
The stack consists of:
an array A of a default size (≥ 1),
the variable top that refers to the top element in the
stack, top changes from -1 to capacity – 1.
the capacity that refers to the array size.
The stack is empty when top = -1, and the stack is full
when top = capacity-1.
Stacks
A Simple Array-Based Stack Implementation
public class ArrayStack<T> implements
StackInterface<T> {
private static final int DEFAULT_CAPACITY = 15;
private int top;//reference to the top element
private T[] A;
public ArrayStack(int initialCapacity) {
if (initialCapacity <= 0)
A = (T[]) new Object[DEFAULT_CAPACITY];
else
A = (T[]) new Object[initialCapacity];
top = -1; // stack is empty
}
Stacks
A Simple Array-Based Stack Implementation
public boolean isEmpty() {
return top == -1;
}
public void clear() {
for (int i = 0; i <= top; i++)
A[i] = null;
top = -1;
}
@Override
public int size() {
return (top + 1);
}
Stacks
A Simple Array-Based Stack Implementation
public T peek() {
if (isEmpty())
throw new StackException("Stack is
empty");
return A[top];
}
public T pop() {
T x = peek();
A[top] = null; // make sure the object is destroyed
top--;
return x;
}
Stacks
A Simple Array-Based Stack Implementation
public void push(T e) {
if (top == A.length)
throw new StackException("Stack has
overflowed");
top++;
A[top] = e;
}
public T top() throws StackException {
if(isEmpty())
throw new StackException("Stack is
empty");
return A[top];
}
Stacks
A drawback with ArrayStack
The array implementation of a stack is simple and
efficient but you have to asssume a fixed upper bound,
CAPACITY.
If you chose the CAPACITY value 1,000 more or less
arbitrarily.
An application may actually need much less space than this,
which would waste memory.
An application may need more space than this, which would
cause our stack implementation to generate an exception as
soon as a client program tries to push its 1,001st object
on the stack.
Stacks
Implementing a Stack with a
Generic Linked List
The top of the stack is at the head of the list.
In order to perform operation size in constant time, we
keep track of the current number of elements in an
instance variable.
When we push a new element e on the stack, we simply
create a new node v for e, reference e from v, and insert v
at the head of the list.
When we pop an element, simply remove the node at the
head of the list and return its element.
We perform all insertions and removals of elements at the
head of the list.
Stacks
Node class
public class Node<T> {
public T data;
public Node<T> next;
public Node(T data) {
this(data, null);
}
public Node(T data, Node<T> n) {
this.data = data;
next = n;
}
}
Stacks
ListStack class
public class ListStack<T> implements Stack<T> {
private Node<T> top;
protected int size;
public ListStack() {
top = null;
size = 0;
}
public boolean isEmpty() {
return top == null;
}
public void clear() {
top = null;
}
Stacks
ListStack class
public int size() {
return size;
}
public T top() throws StackException {
if (isEmpty())
throw new StackException("Stack is
empty");
return top.data;
}
public void push(T data) {
top = new Node<T>(data, top);
}
Stacks
ListStack class
/**Removes and returns the item at the top*/
public T pop() {
if (isEmpty())
throw new StackException("Stack is empty");
T data = top.data;
top = top.next;
return data;
}
Stacks
ListStack class
/**Returns the top item without its removal*/
public T peek() {
if (isEmpty())
throw new StackException("Stack is empty");
return top.data;
}
Stacks
Application of Stacks
Postfix Expressions Calculator
Converting a Number from Decimal to Binary
Stacks
1. Postfix Expressions Calculator
The usual notation for writing arithmetic expressions (the
notation we learned in elementary school) is called infix
notation, in which the operator is written between
the operands, for example: a + b
In the early 1920s, the Polish mathematician Jan
Lukasiewicz discovered that if operators were written
before the operands (prefix or Polish notation; for
example, + a b), the parentheses can be omitted.
Stacks
1. Postfix Expressions Calculator
In the late 1950s, the Australian philosopher and early
computer scientist Charles L. Hamblin proposed a scheme
in which the operators follow the operands (postfix
operators), resulting in the Reverse Polish notation.
This has the advantage that the operators appear in the order
required for computation.
For example:
the expression: a + b * c
in a postfix expression is: a b c * +
Stacks
1. Postfix Expressions Calculator
Stacks