stacks - rana atef tarabishi equivalent to the traditional (infix) expression 15 - 8 7 postfix...
TRANSCRIPT
1
Stacks
(Section 5)
College of Computer Science and Engineering
Taibah University
S1, 1438
Algorithms and Data Structures(CS211 & CS202)
Lecture Scope
Stacks
Stack Implementations
Using an Array
Using a Linked List
Stacks Analysis (Complexity Analysis)
As array
As Linked List
2
2
Stacks
A stack is a classic collection used to help solve many
types of problems
A stack is a linear collection whose elements are added
in a last in, first out (LIFO) manner. That is, the last
element to be put on a stack is the first one to be
removed
Think of a stack of books, where you add and remove
from the top, but can't reach into the middle
3
4
Stacks (cont…)
3
Stack Operations
Some collections use particular terms for their operations
These are the classic stack operations:
5
Stacks in the Java API
The java.util.Stack class has been part of the Java
collections API since Java 1.0. It implements the
classic operations, without any separate interfaces
defined.
6
4
Example: Postfix Expressions
Let's see how a stack can be used to help us solve the
problem of evaluating postfix expressions
A postfix expression is written with the operator following
the two operands instead of between them:
15 8 -
is equivalent to the traditional (infix) expression
15 - 8
7
Postfix expressions eliminate the need for parentheses
to specify the order of operations
The infix expression
(3 * 4 – (2 + 5)) * 4 / 2
is equivalent to the postfix expression
3 4 * 2 5 + – 4 * 2 /
8
Example: Postfix Expressions (cont…)
5
We'll use a stack as follows to evaluate a postfix
expression:
Scan the expression left to right
When an operand is encountered, push it on the stack
When an operator is encountered, pop the top two elements
on the stack, perform the operation, then push the result on
the stack
When the expression is exhausted, the value on the
stack is the final result
9
Example: Postfix Expressions (cont…)
Here's how the stack changes as the following expression is
evaluated:
7 4 -3 * 1 5 + / *
10
Example: Postfix Expressions (cont…)
6
In next implementation, a stack is a container that extends the
AbstractContainer class and implements the Stack interface.
Two implementations:
StackAsArray
The underlying data structure is an array of Object
StackAsLinkedList
The underlying data structure is an object of MyLinkedList
public interface Stack {
public Object getTop();
public void push(Object obj);
public Object pop();
}
Stack Implementations
11
A Stack Interface
12
7
package jsjf;
/**
* Defines the interface to a stack collection.
*
* @author Lewis and Chase
* @version 4.0
*/
public interface StackADT<T>
{
/**
* Adds the specified element to the top of this stack.
* @param element element to be pushed onto the stack
*/
public void push(T element);
/**
* Removes and returns the top element from this stack.
* @return the element removed from the stack
*/
public T pop();
/**
* Returns without removing the top element of this stack.
* @return the element on top of the stack
*/
public T peek();
/**
* Returns true if this stack contains no elements.
* @return true if the stack is empty
*/
public boolean isEmpty();
/**
* Returns the number of elements in this stack.
* @return the number of elements in the stack
*/
public int size();
/**
* Returns a string representation of this stack.
* @return a string representation of the stack
*/
public String toString();
}
13
A Stack Interface (cont…)
Let's now explore our own implementation of a stack,
using an array as the underlying structure in which
we'll store the stack elements
We'll have to take into account the possibility that the
array could become full
And remember that an array of objects really stores
references to those objects
14
Implementing a Stack Using an Array (cont…)
8
Implementing a Stack Using an Array (cont…)
An array of object references:
15
A stack with elements A, B, C, and D pushed on in
that order:
16
Implementing a Stack Using an Array (cont…)
9
Pushing and Popping a Stack
After pushing element E:
After popping:
17
Example:
18
Pushing and Popping a Stack (cont…)
10
19
Pushing and Popping a Stack (cont…)
Example:
Using a stack to reverse spelling
If the program read in CHAD, then it will output DAHC
C
push in : CHAD
pop out :
CH
push in : CHAD
pop out :
CHA
push in : CHAD
pop out :
CHAD
push in : CHAD
pop out :
CHA
push in : CHAD
pop out :D
CH
push in : CHAD
pop out :DA
C
push in : CHAD
pop out : DAH
push in : CHAD
pop out : DAHC
The process of putting a new data element onto stack is known
as PUSH Operation. Push operation involves series of steps −
Step 1 − Check if stack is full.
Step 2 − If stack is full, produce error and exit.
Step 3 − If stack is not full, increment top to point next empty
space.
Step 4 − Add data element to the stack location, where top is
pointing.
Step 5 − return success.
20
Push Operation
11
21
Push Operation (cont…)
Accessing the content while removing it from stack, is known as pop operation.
In array implementation of pop() operation, data element is not actually
removed, instead top is decremented to a lower position in stack to point to
next value. But in linked-list implementation, pop() actually removes data
element and deallocates memory space.
A POP operation may involve the following steps −
Step 1 − Check if stack is empty.
Step 2 − If stack is empty, produce error and exit.
Step 3 − If stack is not empty, access the data element at which top is
pointing.
Step 4 − Decrease the value of top by 1.
Step 5 − return success.
22
Pop Operation
12
23
Pop Operation (cont…)
Managing Capacity
The number of cells in an array is called its capacity
It's not possible to change the capacity of an array in
Java once it's been created
Therefore, to expand the capacity of the stack, we'll
create a new (larger) array and copy over the elements
This will happen infrequently, and the user of the stack
need not worry about it happening
24
13
25
One disadvantage of using an array to implement a stack is the wasted
space---most of the time most of the array is unused. A more elegant and
economical implementation of a stack uses a linked list, which is a data
structure that links together individual data objects as if they were ``links''
in a ``chain'' of data.
Each time an object is pushed, a cell is constructed, the object is
inserted into the cell, and the cell is linked to the front of the chain of
cells.
The linked list implementation has a simpler internal state and simpler
codings of its methods than the stack whose implementation is based on
an array.
Implementing a Stack Using Links
Since all activity on a stack happens on one end, a
single reference to the front of the list will represent
the top of the stack
26
Implementing a Stack Using Links (cont…)
14
The stack after A, B, C, and D are pushed, in that
order:
27
Implementing a Stack Using Links (cont…)
After E is pushed onto the stack:
28
Implementing a Stack Using Links (cont…)
15
29
Implementing a Stack Using Links (cont…)
Example:
30
Implementing a Stack Using Links (cont…)
Example:
16
Let's now implement our own version of a stack that uses
a linked list to hold the elements
Our LinkedStack<T> class stores a generic type T and
implements the same StackADT<T> interface used
previously
A separate LinearNode<T> class forms the list and hold
a reference to the element stored
An integer count will store how many elements are
currently in the stack
31
Implementing a Stack Using Links (cont…)
package jsjf;
/**
* Represents a node in a linked list.
*
* @author Lewis and Chase
* @version 4.0
*/
public class LinearNode<T>
{
private LinearNode<T> next;
private T element;
/**
* Creates an empty node.
*/
public LinearNode()
{
next = null;
element = null;
}
/**
* Creates a node storing the specified element.
* @param elem element to be stored
*/
public LinearNode(T elem)
{
next = null;
element = elem;
}
32
Implementing a Stack Using Links (cont…)
17
/**
* Returns the node that follows this one.
* @return reference to next node
*/
public LinearNode<T> getNext()
{
return next;
}
/**
* Sets the node that follows this one.
* @param node node to follow this one
*/
public void setNext(LinearNode<T> node)
{
next = node;
}
/**
* Returns the element stored in this node.
* @return element stored at the node
*/
public T getElement()
{
return element;
}
/**
* Sets the element stored in this node.
* @param elem element to be stored at this node
*/
public void setElement(T elem)
{
element = elem;
}
}
33
Implementing a Stack Using Links (cont…)
package jsjf;
import jsjf.exceptions.*;
import java.util.Iterator;
/**
* Represents a linked implementation of a stack.
*
* @author Lewis and Chase
* @version 4.0
*/
public class LinkedStack<T> implements StackADT<T>
{
private int count;
private LinearNode<T> top;
/**
* Creates an empty stack.
*/
public LinkedStack()
{
count = 0;
top = null;
} 34
Implementing a Stack Using Links (cont…)
18
/**
* Adds the specified element to the top of this stack.
* @param element element to be pushed on stack
*/
public void push(T element)
{
LinearNode<T> temp = new LinearNode<T>(element);
temp.setNext(top);
top = temp;
count++;
}
/**
* Removes the element at the top of this stack and returns a
* reference to it.
* @return element from top of stack
* @throws EmptyCollectionException if the stack is empty
*/
public T pop() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
T result = top.getElement();
top = top.getNext();
count--;
return result;
}35
Implementing a Stack Using Links (cont…)
36
Implementing a Stack Using Links (cont…)
19
Applications of stacks
37
operations on long integers
history of visited pages through a Web browser
the undo sequence in a text editor
sequence of method/function calls
evaluating postfix expressions
38
Appendix I: Stacks Analysis
- Complexity Analysis -
Note: some ideas in this section are repeated in another way, or another
representation way
Both are doing the same operation
20
push() method adds an element at the top the stack.
It takes as argument an Object to be pushed.
It first checks if there is room left in the stack. If no room is left, it throws
a ContainerFullException exception. Otherwise, it puts the object into
the array, and then increments count variable by one.
public void push(Object object){
if (count == array.length)
throw new ContainerFullException();
else
array[count++] = object;
}Complexity is O(1)
39
StackAsArray – push() Method
The pop method removes an item from the stack and returns that item.
The pop method first checks if the stack is empty. If the stack is empty,
it throws a ContainerEmptyException. Otherwise, it simply decreases
count by one and returns the item found at the top of the stack.
public Object pop(){
if(count == 0)
throw new ContainerEmptyException();
else {
Object result = array[--count];
array[count] = null;
return result;
}
}Complexity is O(1)
40
StackAsArray – pop() Method
21
getTop() method first checks if the stack is empty.
getTop() method is a stack accessor which returns the top item in the
stack without removing that item. If the stack is empty, it throws a
ContainerEmptyException. Otherwise, it returns the top item found
at position count-1.
public Object getTop(){
if(count == 0)
throw new ContainerEmptyException();
else
return array[count – 1];
}Complexity is O(1)
41
StackAsArray – getTop() Method
public void push(Object obj){
list.prepend(obj);
count++;
}
public Object pop(){
if(count == 0)
throw new ContainerEmptyException();
else{
Object obj = list.getFirst();
list.extractFirst();
count--;
return obj;
}
}
public Object getTop(){
if(count == 0)
throw new ContainerEmptyException();
else
return list.getFirst();
}
Complexity is O(1)
Complexity is O(1)
Complexity is O(1)
42
StackAsLinkedList Implementation
22
Appendix II: ImplementationSource: Drozdek, Data Structures & Algorithms in Java
Note: as usual, there are different ways to implement any algorithm
(depending on the programmer).
Just be sure that you are saving the basic idea of the algorithm
43
Array List Implementation of a Stack
44
23
Linked List Implementation of a Stack
45
Summary
Stack elements are processed in a LIFO manner—the last element in is the first
element out.
The java.util.Stack class has been part of the Java collections API.
A stack is the ideal data structure to use when evaluating a postfix expression.
The process of putting a new data element onto stack is known as PUSH Operation.
Accessing the content while removing it from stack, is known as POP operation.
The linked list implementation has a simpler internal state and simpler codings of its
methods than the stack whose implementation is based on an array.
It is easy to see that in the array list and linked list implementations, popping and
pushing are executed in constant time O(1). However, in the array list implementation,
pushing an element onto a full stack requires allocating more memory and copies the
elements from the existing array list to a new array list. Therefore, in the worst case,
pushing takes O(n) time to finish.
46
24
References
Java Software Structures - Designing and Using Data Structures, 4th edition,
Lewis and Chase.
Data Structures & Algorithms in Java, 3rd edition,
Data Structures and Algorithm Analysis in Java, 3rd edition, Weiss
Data Structures and Algorithms in Java, 6th edition, Goodrich, Tamassia and
Goldwasser.
Slides at: http://faculty.kfupm.edu.sa/ICS/jauhar/ics202/
47
Any Question
???
48