Stacks and Queues
-
Upload
gobara-dhan -
Category
Documents
-
view
13 -
download
2
description
Transcript of Stacks and Queues
M.A. Eljinini, PhD
Data Structures
Linear Data Structures
Stacks & Queues
By
Dr. Mohammad Ali H. Eljinini
M.A. Eljinini, PhD
Linear Data Structures
• Are collections of items arranged in a straight line (i.e. in array, or maybe. . . linked list!)
Stacks and Queues are linear data structures, where data can be stored linearly!
• However:
Some rules are applied when adding and removing items from Stacks and Queues.
• So, let us start with Stacks!
M.A. Eljinini, PhD
Stacks
• A stack is a container where the last item is added (pushed) must comes out first (popped)
• So it is a “Last – In – First – Out”
• LIFO
• Example:
• A long, narrow, one-end, Cars Park:
B C
- Car A must have entered first, then B, and last C!
- Last one in is C, must be the first to come out.
- A is the last to come out, since the first pushed in.
A
M.A. Eljinini, PhD
Stacks – another example
• Look at this code (decimal-to-binary):
• K = 13;
• While ( k != 0 ){
• System.out.print(k%2); // print 0’s and 1’s
• k = k /2;
• }
• What is wrong with this code?• 0’s and 1’s are printed in reverse order !!
• One solution is to use Stacks !!• Push 0’s and 1’s inside a stack (i.e. replace the print with
push)
• Then in another loop, start popping and printing !!
• So, Last item entered in the stack, will be removed and printed first, then the one before last, until we get to the first one entered.
Output:1011
M.A. Eljinini, PhD
Stacks – another example
• Version 2 – correct output using a stack:
• k = 13;
• While ( k != 0 ){
• s.push(k%2); // push remainders in stack S
• k = k /2;
• }• While( !s.empty() )
• System.out.print( s.pop() ); // pop items from s and print
Correct Output:1101
0 11 1
1 1 0 1
1
2Stack S
M.A. Eljinini, PhD
Stack: Array-Based Representation• Now, we need to define a Data Structure of the
Stack.
• Then, we need to write the operations (i.e. methods) push, pop, empty, and init.
public class Stack{ // A new class Stack
private int top; // top: index of last item entered
private int items[ ] = new int[10];
}
Stack (a new class - a class )
itemstop
M.A. Eljinini, PhD
Stack: Array-Base Representation:
Now, we can declare S of Type Stack:
Stack S;
Then, we can store a 0 in top: (remember top is int )
top = 0;
And (for example) ‘A’ in first location of array items:
items[0] = ‘A’;
itemstop
S
S
A0itemstop
M.A. Eljinini, PhD
Stack: Array-Base Representation
or, we can declare S as a reference of type Stack:
Stack S;
Then we can use new to instantiate a stack:
S = new Stack();
And assign values:
top = 0;
items[0] = ‘A’;
S
A0itemstop
S
M.A. Eljinini, PhD
Stack: Operations
But, what did happen to LIFO??
We need now to write functions push(), pop(), init(),
and empty(), so we can access the Stack ONLY via
these operations ! Let’s start with init():
void init( ) // Used to initialize the stack
{
top = -1; // if top has -1 stack is empty !!
}
And empty():
boolean empty( ) // return true if empty !
{
return (top == -1); // == logical operation
} // not assignment !!
M.A. Eljinini, PhD
Stack: Operations
And push() to add new item to the stack:
public void push( itemType x) // x: item to add
{
if( top == MAX-1 ){ // if top reached max size
System.out.println(“Error: Stack is full”);
}
else
// first, increment top by 1, the next empty slot.
// then insert x inside items at location [top]
items[ ++top] = x;
}
M.A. Eljinini, PhD
Stack: Operations
Finally, pop() to remove and return last item added in the stack:
itemType pop( ) // Return type of itemType
{
if( s.empty() ){ // if empty we cannot remove items
System.out.println(“Error: Stack is empty”);
}
else
// first, decrement top by 1,to the last full slot.
// then return the value in that slot
return ( items[--top] );
}
M.A. Eljinini, PhD
Stack : OperationsNotes:1. Always, stacks are accessed via the methods push()
pop(), init(), and empty() only!
This way we can insure the when we use pop(), the
last item inserted will be the one to be removed
and returned.
In other words, these functions control the
mechanisms in which the stack operates
2. To change the size of the stack, change the value
of MAX.
3. To use stack with other types than chars, change
the type “itemType” to any type you may need
(i.e. floats, arrays, other structures, etc.)
M.A. Eljinini, PhD
Stack: Linked-Based Representation• In Linked-Based Stack, array items is replaced
with a linked list! And, Stack functions need to be re-implemented to work with the linked list
public class StackNode{
private int item; // Holds the item to be pushed
private Stack next; // Referes to next node
// implement set and get for item and next
} // It is just a node
item link
M.A. Eljinini, PhD
Stack: Linked-Based Representationpublic class stack{
private StackNode L;
public void push(int x)
{ // create new node and insert in L before first }
public int pop()
{ // return data in first node and move it }
} item link
B
L item link
NULLCA
item link
When push: s.push(‘A’); Add the new node at the Beginning
When pop: x=s.pop();Return the item in this nodethen remove it from the list.
The implementation of these functions are left as exercise
M.A. Eljinini, PhD
Exercises - Stacks
1. Implement a linked-based stack complete with the
operations.
2. Write a complete program “Decimal-to-Binary”,
using the stack implemented in 1 above.
3. Write a program to reverse the order of nodes on a
list using a stack.
4. Think of other uses for stacks and list them.
M.A. Eljinini, PhD
Queues
• A Queue is a container where the first item inserted must comes out first. (a waiting line)
• So it is a “First – in – First – Out”
• FIFO
• Example:
• A long, narrow, open-ends, Cars Park:
B C
- Car A must have entered first, then B, and last C!
- First one in is A, must be the first to come out.
- C is the last to come out, since the Last one in.
A
M.A. Eljinini, PhD
Queue: Array-Based Representation• Now, we need to define a Data Structure of the
Queue. Then, we need to write the operations insert, remove, empty, and init.
public class Queue{ // A Queue to hold 10 Characters
private int front, rear, count; // Why 3 variables ?
private char items[10]; // array of 10 characters
// we just need to define the methods of the queue
} // The new type is called Queue !
Queue (a new type - a class )
itemsfront rear count
M.A. Eljinini, PhD
Queue: Array-Based Representation• Problem:
If we keep inserting items at rear, and remove items
from front, then we will need a mechanism for
shifting items every time a new item is added !
• Solution:
We shall use Circular Queues !
C
D E
F
����
�����
C D E F
����� ����
front = (front + 1) % N
rear = (rear +1 ) % N
M.A. Eljinini, PhD
Queues: Operations
We need now to write functions insert(), remove(),
init(), and empty(), so we can access the Queue
ONLY via these operations ! Let’s start with init():
public void init( ) // Used to initialize the queue
{
front = 0; // index of first item in the array
rear = 0; // index of last item
count = 0; // number of items in the array of the queue
}
And empty():
public boolean empty( ) // return true if Queue is empty !
{
return (count == 0); // Zero items in Queue
}
M.A. Eljinini, PhD
Queues: Operations
Now the insert() method:
public void insert( char r) // r is the item of type char to add
{
if(count != MAX) { // Check if Max is reached !
System.out.println(“Error: Queue is Full.”);
}
else { // Now we need to add r at the rear of the queue
// i.e. in the array items at location hold by rear
items[ rear ] = r;
// increment rear by 1, if MAX is reach switch to Zero !!
rear = (rear + 1) % MAX;
++count; // and Finally increment Count
}
}
M.A. Eljinini, PhD
Queues: Operations
And the Remove() method:
public char remove( ) // remove the first item inserted
{ // and return it the calling function
if(count != 0) { // if no items exist, nothing can be removed
System.out.println(“Error: Queue is Empty.”);
}
else {
- - (count); // decrement count
// increment Front by 1, if Zero is reach switch to MAX !!
front = (front + 1) % MAX;
return ( items [ front ] ); // Return the item at front
}
}
M.A. Eljinini, PhD
Queue: Linked-Based Representation• Like the Linked-Based Stack, array items is
replaced with a linked list! And, the functions need to be re-implemented to work with the linked list
public class QNode{ // the object to hold the data
char item; // Holds the item to be inserted
QNode link; // referes to next node in Queue
// do not forget to implement set and get methods
} // It is just a node !
We may use another class to reference front and
rear:
public class Queue{
QNode front;
QNode rear;
} Queue;
Queue: Linked-Based Representation• Why two classes?
item link
B
Q
item link
NULLCA
item link
To Remove front item:1. Return item at front2. Move front to next node
3. Free the first node. Do not forget to have a reference refer to this first node at first place!
To insert item at Rear:1. Create new node of type
QNode2. Link the new node at end3. Let rear points to the
new node
front rear
The implementation of these methods are left as exercise
M.A. Eljinini, PhD
Applications of Stacks
1. Use stacks to balance parentheses in infix
notation
Example:
a * ( b + c ) – ( ( a + b ) / c ))
The number of left parentheses must equal to the
number of right parentheses.
To check for this, we may use a stack, for simple
example, when we encounter a right parentheses;
push it in the stack and when we encounter a left
parentheses pop one right parentheses from the
stack; at end the stack should be empty.
Exercise:
Programs in C language uses brackets “{“ and “}”
as begin and end of function, code blocks, etc.
write a program to read a source code file in C,
and check to see if the brackets are balanced
(i.e. no missing or extra brackets exist).
M.A. Eljinini, PhD
Applications of Stacks
2. Use stacks in mathematical expressions:
1. Infix Notation: (A+B)
2. Prefix Notation: +AB
3. Postfix Notation: AB+
I. Transform infix to prefix:
a. Insert parentheses, where:
left = right = number of operations
b. cancel all right parentheses
c. Exchange all remaining left parentheses with
their operations.
Example:
B + C * D
( B + ( C * D ) )
( B + ( C * D
+ B * C D
M.A. Eljinini, PhD
Applications of Stacks
II.Transform infix to postfix:
a. Insert parentheses, where:
left = right = number of operations
b. cancel all left parentheses
c. Exchange all remaining right parentheses
with their operations.
Example:
B + C * D
( B + ( C * D ) )
B + C * D ) )
B C D * +
Question: So, when do we use the stack??
Answer: we use a stack when we transform from prefix
to infix, or from postfix to infix ! How?
M.A. Eljinini, PhD
Applications of Stacks
III. Transform postfix to infix:
a. Push each operand in the stack until an
operation is encountered.
b. Pop two operands and wrap them around
their operation.
c. repeat until done.
Example:
B C D * + Now:* Now:+
D
C (C*D)
B B (B+(C*D))
VI. Transform Prefix to infix:
Same as above, but we start parsing from right
to left.
Example: + B * C D
1 2 3
(Push each)
M.A. Eljinini, PhD
Applications of Stacks
V. Transform postfix to prefix:
Postfix -> infix -> prefix (Nothing new !)
IV. Transform prefix to postfix:
Prefix -> infix -> postfix (same)
their operation.
3. Use stacks to evaluate postfix:
Example:
10 2 / 3 + Now:’/’ Now:’+’
2 3
10 (10/2) 8
Exercise:Write a Program to read a postfix from the
keyboard, the program then should evaluate the
expression, and output the result.
M.A. Eljinini, PhD
Applications of Stacks
4. Stacks are also used in executing recursion
functions.
Compilers have internal stacks that are used to
hold all parameters and local variables of the
recursive function at each call.
The stack contains “activation frames” instead of
simple types such as int or chars.
Method used:
When the executed recursive function reach the
base, the parameters and variables of the last
function call ( pushed last ) comes out first
(i.e. returned first)!
then the one before last and so on, in reverse
order, as expected.
M.A. Eljinini, PhD
Applications of Queues
1. Queues in Operating Systems:
Acts as buffers to help synchronize interactions
between two processes that run at different
speeds.
Example 1: Print Buffer (in memory)
The CPU may produce output to be printed much
faster than the printer can print it. The data is
then stored in “Print Buffer” which is a reserved
location in memory, that works as (FIFO) – First
jobs in, First to get printed!
Example 2: Print Spooler (in file)
This is used on the network (many PC’s are
connected to one printer via a server). When
several users try to print at the same time, the
print jobs are placed in a file on the server
which acts like a queue – First received get
printed first.
M.A. Eljinini, PhD
Applications of Queues2. Queues in Simulation experiments:
The use of computers to model systems so we can
study it and understand it. Serviced
Example: Waiting Lines (FIFS)
- Supermarket checkout
- Bank tellers
- Cars at gas stations
- Plains waiting to takeoff
- Drive-through windows of fast food outlets
- Cars at traffic lights.
- and many more.
What do we simulate in real-world systems?
- Arrival rates of clients
- Service Time
Why?
To Collect statistics on the overall
System performance.
M.A. Eljinini, PhD
Applications of QueuesFor example, to measure:
- Average waiting time to obtain service
- Variance in waiting time (i.e. how dispersed
or spread out the waiting times are)
- Length of the Queue
- Throughput of the system (i.e. number of
clients served per hour)
Usually the simulations are run under different
conditions. For example, varying number of tellers
at different times at the bank!
Benefits:
Marketing fast Service !!
M.A. Eljinini, PhD
Exercise: Stacks & QueuesThe Palindrome Problem:
Write a program using a stack and a queue to do the
following:
- Read a file, one line a time (to be prepared
in advance)
- The program to determine if each line is a
palindrome
- output the line (in another file, or on the
screen) and if palindrome or not.
What is a palindrome?
A line (or string) that if read left to write or
right to left produce the same, is a palindrome.
Examples:
- MAM
- “1234321”
- abababa
- able was I ere I saw elba