unit 4: stacks and queues · stack to store each delimeter until its mate is found:...

24
Unit 4: Stacks and Queues Engineering 4892: Data Structures Faculty of Engineering & Applied Science Memorial University of Newfoundland June 1, 2011 ENGI 4892 (MUN) Unit 4 June 1, 2011 1 / 24

Upload: others

Post on 19-Jul-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Unit 4: Stacks and Queues

Engineering 4892:Data Structures

Faculty of Engineering & Applied ScienceMemorial University of Newfoundland

June 1, 2011

ENGI 4892 (MUN) Unit 4 June 1, 2011 1 / 24

Page 2: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

1 Stacks

1 Stacks in STL

1 Case study: exiting a maze

1 Queues

ENGI 4892 (MUN) Unit 4 June 1, 2011 2 / 24

Page 3: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Stacks

A stack is a list of items accessed only through one end of the list. It issometimes referred to as a LIFO structure, meaning last in / first out.

A stack is sometimes visualized as growing upwards, like a real “stack” oftrays in a cafeteria. Hence, the accessible end of the stack is referred to asthe top of the stack.

Stack operations:

clear() Emptys the stack.

isEmpty() Checks to see if the stack is empty.

push(el) Puts the element el on top of the stack.

pop() Takes the top-most element off the stack.

topEl() Returns the top-most element, without removing it.

ENGI 4892 (MUN) Unit 4 June 1, 2011 3 / 24

Page 4: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Demonstration of stack operations:

Stacks are useful when we need to store data and then access it again inreverse order.

e.g. Matching delimiters in C++. In C++ the following delimeters mustexist in matched pairs: ( ) [ ] { }

Matching pairs of delimeters can be nested within each other. We canmatch a pair only after all the delimeters between them have been dealtwith.

ENGI 4892 (MUN) Unit 4 June 1, 2011 4 / 24

Page 5: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

The following algorithm (given in pseudocode) matches delimeters using astack to store each delimeter until its mate is found:

delimeterMatching(file)

while not end-of-file

read character ch from file;

if ch is ‘(’, ‘[’, or ‘{’push(ch);

else if ch is ‘)’, ‘]‘, or ‘}’if stack is empty

failure;

mate = pop();

if ch and mate do not match

failure;

if stack is empty

success;

else

failure;

(Note that this algorithm does not handle comments appropriately.)

Page 6: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

e.g. s=t[5]+u/(v∗(w+y));

Page 7: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Another example application of stacks involves the addition of very largenumbers. The sum,

234,123,574,345,123,050,433 + 1,122,344,556,413,666,990,000,121

...does not fit in an int. This can be addressed by breaking each numberinto its numerals and putting these numerals on a stack.

Addition then involves an operation on two stacks with one stack as anoutput (representing the result).

First, each number is broken into numerals and these are pushed onto thestack in order of decreasing significance.

ENGI 4892 (MUN) Unit 4 June 1, 2011 7 / 24

Page 8: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

addingLargeNumbers()

read the first number and push onto stack1;

read the second number and push onto stack2;

result = 0;

while at least one stack is not empty

if stack1 is not empty

result += stack1.pop();

if stack2 is not empty

result += stack2.pop();

push the unit part of result onto output stack ;

result = the 10’s part of result;

push result onto output stack if non-zero ;

pop numerals from output stack and display them ;

The application of addingLargeNumbers to the addition of 592 and 3784is shown on the following slide...

Page 9: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be
Page 10: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Stacks in STL

STL defines a generic stack class called stack. By default, it is anadaptation of the doubly-ended queue class deque. However, it can becustomized to use a DLL (represented in STL as a list) or an array(represented in STL as a vector) as its underlying implementation:

stack<int> stack1 ; // deque by d e f a u l tstack<int , vector<int> > stack2 ; // v e c t o r ( i . e . a r r a y )stack<int , list<int> > stack3 ; // l i s t ( i . e . DLL)

ENGI 4892 (MUN) Unit 4 June 1, 2011 10 / 24

Page 11: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

STL defines all of the expected stack operations. However, pop onlyremoves the top element—it does not return it. The following Stack classcan be used to obtain the usual popping behaviour:

template<class T>class Stack : public stack<T> {public :

T pop ( ) {T tmp = stack<T> : : top ( ) ;stack<T> : : pop ( ) ;return tmp ;

}} ;

ENGI 4892 (MUN) Unit 4 June 1, 2011 11 / 24

Page 12: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Case study: exiting a mazeConsider a mouse trapped in a maze, trying to find the exit:

This mouse can only move right, left, down, or up—one step at a time. Itapplies the following procedure:

Try moving right, left, down, and up

If a route beginning with any one of these fails, try a new route thatstarts in an untried direction

A stack is used to remember untried positions and to organize the order inwhich these positions are attempted.

Page 13: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

The maze is implemented as a 2D array of char’s

1 = wall

0 = open

m = mouse’s initial position

e = exit (could be anywhere)

. = visited location

We assume the boundaries of the array are either walls or the exit.

Page 14: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

The following is the pseudocode for the mouse’s stack-based solution:

exitMaze()

initialize stack;

currentCell = entryCell;

while currentCell != exitCell

mark currentCell as visited ;

push onto stack currentCell’s unvisited neighbours;

if stack is empty

failure;

else

currentCell = stack.pop();

success;

Unvisited neighbours are pushed in the following order: up, down, left, andright. The order in which neighbours are visited will be opposite: right,left, down, and up.

The stack stores the row and column of each cell that remains to beexplored.

Page 15: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Consider the following example:

Page 16: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Here is part of the C++ implementation:

void Maze : : pushUnvisited ( int row , int col ) {if ( store [ row ] [ col ] == passage | | store [ row ] [ col ] == exitMarker ) {

mazeStack . push ( Cell ( row , col ) ) ;}

}void Maze : : exitMaze ( ) {

int row , col ;currentCell = entryCell ;while ( ! ( currentCell == exitCell ) ) {

row = currentCell . x ;col = currentCell . y ;cout << ∗this ; // p r i n t a snapshot ;if ( ! ( currentCell == entryCell ) )

store [ row ] [ col ] = visited ;pushUnvisited ( row−1,col ) ;pushUnvisited ( row+1,col ) ;pushUnvisited ( row , col−1);pushUnvisited ( row , col+1);if ( mazeStack . empty ( ) ) {

cout << ∗this ;cout << "Failure\n" ;return ;

}else currentCell = mazeStack . pop ( ) ;

}cout << ∗this ;cout << "Success\n" ;

}

ENGI 4892 (MUN) Unit 4 June 1, 2011 16 / 24

Page 17: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Queues

A queue is essentially a line-up. Items are added to the back of the queueand are later accessed from the front. A queue is sometimes referred to asa FIFO structure, meaning first in / first out.

Queue operations:

clear() Emptys the queue.

isEmpty() Checks to see if the queue is empty.

enqueue(el) Puts the element el at the end of the queue.

dequeue() Takes the first element from the queue.

firstEl() Returns the top-most element, without removing it.

ENGI 4892 (MUN) Unit 4 June 1, 2011 17 / 24

Page 18: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Demonstration of queue operations:

A queue can be implemented efficiently as a doubly-linked list. If thequeue has a fixed maximum size, it can also be implemented as an array.

The array-based implementation uses two indices, first and last to keeptrack of the position of the queue within the array...

ENGI 4892 (MUN) Unit 4 June 1, 2011 18 / 24

Page 19: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

ENGI 4892 (MUN) Unit 4 June 1, 2011 19 / 24

Page 20: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

How do we represent the empty queue? first = −1, last = −1

How do we tell if the queue is full?

If first happens to be at 0, the queue is full if last == size−1.

If first > 0, the queue is full if last == first − 1

The following is the code for an array-based queue...

ENGI 4892 (MUN) Unit 4 June 1, 2011 20 / 24

Page 21: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

template<class T , int size = 100>class ArrayQueue {public :

ArrayQueue ( ) {first = last = −1;

}void enqueue (T ) ;T dequeue ( ) ;bool isFull ( ) {

return first == 0 && last == size−1 | |first == last + 1 ;

}bool isEmpty ( ) {

return first == −1;}

private :int first , last ;T storage [ size ] ;

} ;

Consider the operation of enqueueing...ENGI 4892 (MUN) Unit 4 June 1, 2011 21 / 24

Page 22: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Check if queue is fullIn general,

Increment lastPlace element in storage[last]

If last is at the end of the array,Set last = 0Place element in storage[last]

Special case: Enqueueing into an empty queue. This can be handled likethe second case, but we must also set first = 0.

template<class T , int size>void ArrayQueue<T , size> : : enqueue (T el ) {

if ( ! isFull ( ) )if ( last == size−1 | | last == −1) {

storage [ 0 ] = el ;last = 0 ;if ( first == −1)

first = 0 ;}else storage[++last ] = el ;

else cout << "Full queue.\n" ;}

Page 23: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

Consider the operation of dequeueing:

Store the value of the first elementIn general,

Increment firstIf first is at the end of the array,

Set first = 0

Special cases

Dequeueing the last element. Handled by setting first = last = −1

Dequeueing on the empty queue. Forbidden by precondition.

template<class T , int size>T ArrayQueue<T , size> : : dequeue ( ) {

T tmp ;tmp = storage [ first ] ;if ( first == last )

last = first = −1;else if ( first == size−1)

first = 0 ;else first++;return tmp ;

}

Page 24: Unit 4: Stacks and Queues · stack to store each delimeter until its mate is found: delimeterMatching(file) ... adaptation of the doubly-ended queue class deque. However, it can be

The following shows how the storage array changes as operations occur:

The top figure shows the operations on an abstract queue. The bottomfigure shows the operations on an ArrayQueue (the array is shownupside-down).

ENGI 4892 (MUN) Unit 4 June 1, 2011 24 / 24