Chapter 17: Stacks and Queues Java Programming: Program Design Including Data Structures Program...
-
Upload
russell-bates -
Category
Documents
-
view
233 -
download
0
Transcript of Chapter 17: Stacks and Queues Java Programming: Program Design Including Data Structures Program...
Chapter 17: Stacks and QueuesChapter 17: Stacks and Queues
Java Programming: Java Programming: Program Design Including Data Program Design Including Data StructuresStructures
Java Programming: Program Design Including Data Structures 2
Chapter Objectives
Learn about stacks Examine various stack operations Learn how to implement a stack as an array Learn how to implement a stack as a linked list Discover stack applications
Java Programming: Program Design Including Data Structures 3
Chapter Objectives (continued)
Learn how to use a stack to remove recursion Learn about queues Examine various queue operations Learn how to implement a queue as an array Discover queue applications
Java Programming: Program Design Including Data Structures 4
Stacks
Lists of homogeneous elements Addition and deletion of elements occur only at one
end, called the top of the stack Computers use stacks to implement method calls Stacks are also used to convert recursive algorithms
into nonrecursive algorithms Especially recursive algorithms that are not tail
recursive
Java Programming: Program Design Including Data Structures 5
Stacks (continued)
Figure 17-1 Various types of stacks
Java Programming: Program Design Including Data Structures 6
Stacks (continued)
Stacks are also called Last Input First Output (LIFO) data structures
Operations performed on stacks Push: adds an element to the stack Pop: removes an element from the stack Peek: looks at the top element of the stack
Java Programming: Program Design Including Data Structures 7
Stacks (continued)
Figure 17-3 Stack operations
Java Programming: Program Design Including Data Structures 8
Stacks (continued)
Figure 17-4 UML diagram of the interface StackADT
public class StackADT<T> {…
}
Java Programming: Program Design Including Data Structures 9
StackException Class
Adding an element to a full stack and removing an element from an empty stack would generate errors or exceptions Stack overflow exception Stack underflow exception
Classes that handle these exceptions StackException extends RunTimeException StackOverflowException extends StackException StackUnderflowException extends StackException
Java Programming: Program Design Including Data Structures 10
Implementation of Stacks as Arrays
The array implementing a stack is an array of reference variables
Each element of the stack can be assigned to an array slot
The top of the stack is the index of the last element added to the stack
To keep track of the top position, declare a variable called stackTop
Java Programming: Program Design Including Data Structures 11
Implementation of Stacks as Arrays (continued)
Figure 17-5 UML class diagram of the class StackClass
public class StackClass<T> implements StackADT<T> {…
}
Java Programming: Program Design Including Data Structures 12
Implementation of Stacks as Arrays (continued)
public class StackClass<T> implements StackADT<T> { private int maxStackSize; private int stackTop; private T[] list;
…
}
Java Programming: Program Design Including Data Structures 13
Implementation of Stacks as Arrays (continued)
Figure 17-6 Example of a stack
Java Programming: Program Design Including Data Structures 14
Constructors
Default constructorpublic StackClass()
{
maxStackSize = 100;
stackTop = 0; //set stackTop to 0
list = (T[]) new Object[maxStackSize]; //create the array
}//end default constructor
Java Programming: Program Design Including Data Structures 15
Initialize Stack
Method initializeStackpublic void initializeStack()
{
for (int i = 0; i < stackTop; i++)
list[i] = null;
stackTop = 0;
}//end initializeStack
Java Programming: Program Design Including Data Structures 16
Empty Stack
Method isEmptyStackpublic boolean isEmptyStack()
{
return (stackTop == 0);
}//end isEmptyStack
Java Programming: Program Design Including Data Structures 17
Full Stack
Method isFullStackpublic boolean isFullStack()
{
return (stackTop == maxStackSize);
}//end isFullStack
Java Programming: Program Design Including Data Structures 18
Push
Method pushpublic void push(T newItem) throws StackOverflowException
{
if (isFullStack())
throw new StackOverflowException();
list[stackTop] = newItem; //add newItem at the
//top of the stack
stackTop++; //increment stackTop
}//end push
Java Programming: Program Design Including Data Structures 19
Peek
Method peekpublic T peek() throws StackUnderflowException
{
if (isEmptyStack())
throw new StackUnderflowException();
return (T) list[stackTop - 1];
}//end peek
Java Programming: Program Design Including Data Structures 20
Pop
Method poppublic void pop() throws StackUnderflowException
{
if (isEmptyStack())
throw new StackUnderflowException();
stackTop--; //decrement stackTop
list[stackTop] = null;
}//end pop
Java Programming: Program Design Including Data Structures 21
Programming Example: Highest GPA
Program reads a data file consisting of Each student’s GPA followed by the student’s name
Then it prints Highest GPA (stored in the variable highestGPA) The names of all the students with the highest GPA
The program uses a stack to keep track of the name of students with the highest GPA
Java Programming: Program Design Including Data Structures 22
Linked Implementation of Stacks Arrays have fixed sizes
Only a fixed number of elements can be pushed onto the stack
Dynamically allocate memory using reference variables Implement a stack dynamically
Similar to the array representation, stackTop is used to locate the top element stackTop is now a reference variable
Java Programming: Program Design Including Data Structures 23
Linked Implementation of Stacks (continued)
Figure 17-13 Nonempty linked stack
public class LinkedStackClass<T> implements StackADT<T> { private StackNode<T> stackTop;
…}
Java Programming: Program Design Including Data Structures 24
LinkedStackClass & StackNodepublic class LinkedStackClass<T> implements StackADT<T> { private StackNode<T> stackTop;
private class StackNode<T> { public T info; public StackNode<T> link;
…
} // end of StackNode<T> class private LinkedStackClass() { stackTop = null; }
…
} // end of LinkedStackClass<T> class
Java Programming: Program Design Including Data Structures 25
Default Constructor
Default constructorpublic LinkedStackClass()
{
stackTop = null;
}//end constructor
Java Programming: Program Design Including Data Structures 26
Initialize Stack
Method initializeStackpublic void initializeStack()
{
stackTop = null;
}//end initializeStack
Java Programming: Program Design Including Data Structures 27
Empty Stack and Full Stack
Methods isEmptyStack and isFullStackpublic boolean isEmptyStack()
{
return (stackTop == null);
}//end isEmptyStack
public boolean isFullStack()
{
return false;
}//end isFullStack
Java Programming: Program Design Including Data Structures 28
Push
Method pushpublic void push(T newElement)
{
StackNode<T> newNode; //reference variable to create
//the new node
newNode = new
StackNode<T>(newElement, stackTop); //create
//newNode and insert
//before stackTop
stackTop = newNode; //set stackTop to point to
//the top element
} //end push
Java Programming: Program Design Including Data Structures 29
Peek
Method peekpublic T peek() throws StackUnderflowException
{
if (stackTop == null)
throw new StackUnderflowException();
return stackTop.info;
}//end top
Java Programming: Program Design Including Data Structures 30
Pop
Method poppublic void pop() throws StackUnderflowException
{
if (stackTop == null)
throw new StackUnderflowException();
stackTop = stackTop.link; //advance stackTop to the
//next node
}//end pop
Java Programming: Program Design Including Data Structures 31
Stack as Derived from the class UnorderedLinkedList
The class LinkedStackClass can be derived from the class LinkedListClass
The class LinkedListClass is an abstract class You can derive the class LinkedStackClass
from the class UnorderedLinkedList
public class LinkedStackClass<T> extends UnorderedLinkedList<T> {
…}
COSC 237 © R.G. Eyer , 2012 32
Linked ListsInterface…
Iterable
Interface…
Collection
Interface…
Queue
Interface…
Deque
Interface…
List
Class…
LinkedList
Class…
AbstractCollection
Class…
AbstractList
Class…
AbstractSequentialList
Class…
ObjectInterface…
CloneableInterface…
Serializable
Java Programming: Program Design Including Data Structures 33
Applications of Stacks: Postfix Expression Calculator
Infix notation The operator is written between the operands
Prefix or Polish notation Operators are written before the operands Does not require parentheses
Reverse Polish or postfix notation Operators follow the operands Has the advantage that the operators appear in the
order required for computation
Java Programming: Program Design Including Data Structures 34
Applications of Stacks: Postfix Expression Calculator (continued)
Table 17-1 Infix expressions and their equivalent postfix expressions
Java Programming: Program Design Including Data Structures 35
Applications of Stacks: Postfix Expression Calculator (continued)
Algorithm to evaluate postfix expressions using a stack Scan the expression from left to right Operands are pushed onto the stack When an operator is found, back up to get the
required number of operands Perform the operation Continue processing the expression
Java Programming: Program Design Including Data Structures 36
Main Algorithm Main algorithm in pseudocode for processing a
postfix expressionGet the next expressionwhile more data to process{ a. initialize the stack b. process the expression c. output result d. get the next expression}
Java Programming: Program Design Including Data Structures 37
Method evaluateExpression General algorithm for evaluateExpressionget the next tokenwhile (token != '='){ if (token is a number) { output number push number onto stack } else { token is an operation call method evaluateOpr to evaluate the operation } if (no error in the expression) get next token else discard the expression}
Java Programming: Program Design Including Data Structures 38
Method evaluateOpr This method evaluates an arithmetic operation Two operands are needed to evaluate an operation Operands are stored in the stack
The stack must contain at least two operands Otherwise, the operation cannot be evaluated
Java Programming: Program Design Including Data Structures 39
Method printResultpublic static void printResult(StackClass<Double> pStack, PrintWriter outp){ Double result; Double temp; if (expressionOk) //if no error, print the result { if (!pStack.isEmptyStack()) { result = (Double) pStack.peek(); pStack.pop(); if (pStack.isEmptyStack()) outp.printf(“%s %.2f %n”, strToken, result); else outp.println(strToken + “ (Error: Too many operands)”); }//end if else outp.println(“ (Error in the expression)”); } else outp.println(“ (Error in the expression)”); outp.println(“_________________________________”);}//end printResult
Java Programming: Program Design Including Data Structures 40
Postfix Expression Calculator: Graphical User Interface (GUI)
Figure 17-28 GUI for the postfix calculator
Java Programming: Program Design Including Data Structures 41
Postfix Expression Calculator: Graphical User Interface (GUI)
(continued) Methods evaluateExpression, evaluateOpr, and printResult need minor modifications The data are no longer coming from a file The output is no longer stored in a file
To simplify the accessing of the stack Declare it as an instance variable of the class
containing the GUI program
Java Programming: Program Design Including Data Structures 42
Postfix Expression Calculator: Graphical User Interface (GUI)
(continued) To create the GUI, the class containing the GUI must
extend the class JFrame The GUI interface contains several labels, three
buttons, and a textfield When the user clicks a button, it should generate an
action event You need to handle this event
The class constructor creates the GUI components and initialize them
Java Programming: Program Design Including Data Structures 43
Postfix Expression Calculator: Graphical User Interface (GUI)
(continued)
Figure 17-29 Sample run of PostfixCalculator program
Java Programming: Program Design Including Data Structures 44
Removing Recursion: Nonrecursive Algorithm to Print a
Linked List Backward Naïve approach
Get the last node of the list and print it Traverse the link starting at the first node
Repeat this process for every node Traverse the link starting at the first node until you
reach the desired node Very inefficient
Java Programming: Program Design Including Data Structures 45
Removing Recursion: Nonrecursive Algorithm to Print a Linked List Backward (continued)
current = first; //Line 1
while (current != null) //Line 2
{
stack.push(current); //Line 3
current = current.link; //Line 4
}
Java Programming: Program Design Including Data Structures 46
Removing Recursion: Nonrecursive Algorithm to Print a Linked List Backward (continued)
Figure 17-36 List and stack after the staments stack.push(current); and current = current.link; executes
Java Programming: Program Design Including Data Structures 47
The class Stack
Table 17-2 Members of the class Stack
Java Programming: Program Design Including Data Structures 48
Queues Data structure in which the elements are added at
one end, called the rear, and deleted from the other end, called the front
A queue is a First In First Out data structure As in a stack, the middle elements of the queue are
inaccessible
public class QueueADT<T> {…
}
Java Programming: Program Design Including Data Structures 49
Queue Operations Queue operations
initializeQueue isEmptyQueue isFullQueue front back addQueue deleteQueue
Java Programming: Program Design Including Data Structures 50
QueueException Class Adding an element to a full queue and removing an
element from an empty queue would generate errors or exceptions Queue overflow exception Queue underflow exception
Classes that handle these exceptions QueueException extends RunTimeException QueueOverflowException extends QueueException QueueUnderflowException extends QueueException
Java Programming: Program Design Including Data Structures 51
Implementation of Queues as Arrays
Instance variables An array to store the queue elements queueFront: keeps track of the first element queueRear: keeps track of the last element maxQueueSize: specifies the maximum size of the
queues
Java Programming: Program Design Including Data Structures 52
Implementation of Queues as Arrays (continued)
Figure 17-42 Queue after two more addQueue operations
public class QueueClass<T> implements QueueADT<T> {…
}
Java Programming: Program Design Including Data Structures 53
Implementation of Queues as Arrays (continued)
public class QueueClass<T> implements QueueADT<T> { private int maxQueueSize; private int count; private int queueFront; private int queueRear; private T[] list;
…
}
Java Programming: Program Design Including Data Structures 54
Implementation of Queues as Arrays (continued)
Problems with this implementation Arrays have fixed sizes After various insertion and deletion operations, queueRear will point to the last array position Giving the impression that the queue is full
Solutions Slide all of the queue elements toward the first array
position Use a circular array
Java Programming: Program Design Including Data Structures 55
Implementation of Queues as Arrays (continued)
Figure 17-45 Circular queue
Java Programming: Program Design Including Data Structures 56
Implementation of Queues as Arrays (continued)
Figure 17-46 Queue with two elements at positions 98 and 99
Java Programming: Program Design Including Data Structures 57
Implementation of Queues as Arrays (continued)
Figure 17-47 Queue after one more addQueue operation
Java Programming: Program Design Including Data Structures 58
Constructors Default constructor//Default constructor
public QueueClass()
{
maxQueueSize = 100;
queueFront = 0; //initialize queueFront
queueRear = maxQueueSize - 1; //initialize queueRear
count = 0;
list = (T[]) new Object[maxQueueSize]; //create the
//array to implement the queue
}
Java Programming: Program Design Including Data Structures 59
initializeQueue Method initilializeQueuepublic void initializeQueue()
{
for (int i = queueFront; i < queueRear;
i = (i + 1) % maxQueueSize)
list[i] = null;
queueFront = 0;
queueRear = maxQueueSize - 1;
count = 0;
}
Java Programming: Program Design Including Data Structures 60
Empty Queue and Full Queue Methods isEmptyQueue and isFullQueuepublic boolean isEmptyQueue()
{
return (count == 0);
}
public boolean isFullQueue()
{
return (count == maxQueueSize);
}
Java Programming: Program Design Including Data Structures 61
Front Method frontpublic T front() throws QueueUnderflowException
{
if (isEmptyQueue())
throw new QueueUnderflowException();
return (T) list[queueFront];
}
Java Programming: Program Design Including Data Structures 62
Back Method backpublic T back() throws QueueUnderflowException
{
if (isEmptyQueue())
throw new QueueUnderflowException();
return (T) list[queueRear];
}
Java Programming: Program Design Including Data Structures 63
addQueue Method addQueuepublic void addQueue(T queueElement)
throws QueueOverflowException
{
if (isFullQueue())
throw new QueueOverflowException();
queueRear = (queueRear + 1) % maxQueueSize; //use the
//mod operator to advance queueRear
//because the array is circular
count++;
list[queueRear] = queueElement;
}
Java Programming: Program Design Including Data Structures 64
deleteQueue Method deleteQueuepublic void deleteQueue() throws QueueUnderflowException
{
if (isEmptyQueue())
throw new QueueUnderflowException();
count--;
list[queueFront] = null;
queueFront = (queueFront + 1) % maxQueueSize; //use the
//mod operator to advance queueFront
//because the array is circular
}
Java Programming: Program Design Including Data Structures 65
Linked Implementation of Queues
Simplifies many of the special cases of the array implementation
Because the memory to store a queue element is allocated dynamically, the queue is never full
Class LinkedQueueClass implements a queue as a linked data structure It uses nodes of type QueueNode
Java Programming: Program Design Including Data Structures 66
LinkedQueueClass & QueueNodepublic class LinkedQueueClass<T> implements QueueADT<T> { private QueueNode<T> queueFront; private QueueNode<T> queueRear;
private class QueueNode<T> { public T info; public QueueNode<T> link;
…
} // end of QueueNode<T> class private LinkedQueueClass() { queueFront = null; queueRear = null; }
…
} // end of LinkedStackClass<T> class
Java Programming: Program Design Including Data Structures 67
Linked Implementation of Queues (continued)
Method initializeQueuepublic void initializeQueue()
{
queueFront = null;
queueRear = null;
}
Java Programming: Program Design Including Data Structures 68
Linked Implementation of Queues (continued)
Methods isEmptyQueue and isFullQueuepublic boolean isEmptyQueue()
{
return (queueFront == null);
}
public boolean isFullQueue()
{
return false;
}
Java Programming: Program Design Including Data Structures 69
front and back
Methods front and backpublic T front() throws QueueUnderflowException
{
if (isEmptyQueue())
throw new QueueUnderflowException();
return queueFront.info;
}
public T back() throws QueueUnderflowException
{
if (isEmptyQueue())
throw new QueueUnderflowException();
return queueRear.info;
}
Java Programming: Program Design Including Data Structures 70
addQueue
Method addQueuepublic void addQueue(T newElement)
{
QueueNode<T> newNode;
newNode = new QueueNode<T>(newElement, null); //create
//newNode and assign newElement to newNode
if (queueFront == null) //if initially the queue is empty
{
queueFront = newNode;
queueRear = newNode;
}
else //add newNode at the end
{
queueRear.link = newNode;
queueRear = queueRear.link;
}
}//end addQueue
Java Programming: Program Design Including Data Structures 71
deleteQueue
Method deleteQueuepublic void deleteQueue() throws QueueUnderflowException
{
if (isEmptyQueue())
throw new QueueUnderflowException();
queueFront = queueFront.link; //advance queueFront
if (queueFront == null) //if after deletion the queue
queueRear = null; //is empty, set queueRear to null
} //end deleteQueue
public class LinkedQueueClass<T> extends DoublyLinkedList<T> { …}
72
Queue Derived from the class DoublyLinkedList
The class LinkedQueueClass can be derived from the class UnorderedLinkedListClass addQueue and deleteQueue Likewise, the operations initializeQueue, initializeList, isEmptyQueue, and isEmptyList are similar
queueFront is the same as front queueRear is the same as back
Java Programming: Program Design Including Data Structures 73
Application of Queues: Simulation
Simulation A technique in which one system models the behavior
of another system Used when it is too expensive or dangerous to
experiment with real systems You can also design computer models to study the
behavior of real systems Queuing systems
Queues of objects are waiting to be served
Java Programming: Program Design Including Data Structures 74
Designing a Queuing System
Terms Server
Object that provides a service Customer
Object receiving a service Transaction time
The time it takes to serve a customer
Java Programming: Program Design Including Data Structures 75
Designing a Queuing System (continued)
Components List of servers Queue of waiting objects
Process The customer at the front of the queue waits for the
next available server When a server becomes free, the customer at the front
of the queue moves to be served At the beginning, all servers are free
Java Programming: Program Design Including Data Structures 76
Designing a Queuing System (continued)
What you need to know The number of servers The customer expected arrival time The time between the arrivals of customers The number of events affecting the system
Time-driven simulation Uses a clock that can be implemented as a counter The simulation is run for a fixed amount of time
Java Programming: Program Design Including Data Structures 77
Customer
Figure 17-54 UML class diagram of the class Customer
Java Programming: Program Design Including Data Structures 78
Customer (continued)
Methods getWaitingTime and incrementWaitingTime
public int getWaitingTime()
{
return waitingTime;
}
public void incrementWaitingTime()
{
waitingTime++;
}
Java Programming: Program Design Including Data Structures 79
Server
Figure 17-55 UML class diagram of the class Server
Java Programming: Program Design Including Data Structures 80
Server (continued)
Methods setTransactionTime and decreaseTransactionTime
public void setTransactionTime(int t)
{
transactionTime = t;
}
public void setTransactionTime()
{
transactionTime = currentCustomer.getTransactionTime();
}
public void decreaseTransactionTime()
{
transactionTime--;
}
Java Programming: Program Design Including Data Structures 81
Server List
Figure 17-56 UML class diagram of the class serverList
Java Programming: Program Design Including Data Structures 82
Server List (continued)
Method setServerBusypublic void setServerBusy(int serverID, Customer cCustomer,
int tTime)
{
servers[serverID].setBusy();
servers[serverID].setTransactionTime(tTime);
servers[serverID].setCurrentCustomer(cCustomer);
}
public void setServerBusy(int serverID, Customer cCustomer)
{
int time;
time = cCustomer.getTransactionTime();
servers[serverID].setBusy();
servers[serverID].setTransactionTime(time);
servers[serverID].setCurrentCustomer(cCustomer);
}
Java Programming: Program Design Including Data Structures 83
Waiting Customer Queue
Class WaitingCustomerQueueclass WaitingCustomerQueue extends QueueClass
{
public WaitingCustomerQueue()
{
super();
}
public WaitingCustomerQueue(int size)
{
super(size);
}
public void updateWaitingQueue()
{
//...
}
}
Java Programming: Program Design Including Data Structures 84
Main Program
To run the simulation, you need the following simulation parameters Number of time units the simulation should run Number of servers Amount of time it takes to serve a customer
Transaction time Approximate time between customer arrivals
Java Programming: Program Design Including Data Structures 85
Main Program (continued)
General algorithm Declare and initialize the variables, including the
simulation parameters Run the main loop that moves customers from
waiting queue to the next available server and updates simulation times Customer waiting time Server busy time
Print the appropriate results
Java Programming: Program Design Including Data Structures 86
Chapter Summary
Stacks Addition and deletion of elements occur only at one
end, called the top of the stack Follow a LIFO policy
Stack implementation Array-based stacks Linked stacks
Stacks are used to convert recursive algorithms into nonrecursive algorithms
Java Programming: Program Design Including Data Structures 87
Chapter Summary (continued) Queues
Elements are added at one end, called the rear, and deleted from the other end, called the front
Follow a FIFO policy Queue implementation
Array-based queues Linked queues
Queues are used to construct computer-aided simulation programs