Stacks and Queues Sections 3.6 and 3.7
Stack ADT Collections: Elements of some proper type T Operations: void push(T t) void pop() T top() bool empty() unsigned int size() constructor and destructor
Uses of ADT Stack Depth first search / backtracking Evaluating postfix expressions Converting infix to postfix Function calls (runtime stack) Recursion
Stack Model—LIFO Empty stack S S.empty() is true S.top() not defined S.size() == 0 S.push(“mosquito”) S.empty() is false S.top() == “mosquito” S.size() == 1 S.push(“fish”) S.empty() is false S.top() == “fish” S.size() == 2 food chain stack
Stack Model—LIFO S.push(“raccoon”) S.empty() is false S.top() == “raccoon” S.size() == 3 S.pop() S.empty() is false S.top() == “fish” S.size() == 2 food chain stack
Queue ADT - FIFO Collection Elements of some proper type T Operations void push(T t) void pop() T front() bool empty() unsigned int size() Constructors and destructors
Queue Model—FIFO Empty Q animal_parade_queue front back
Queue Model—FIFO Q.push( “ant” ) Q.push( “bee” ) Q.push( “cat” ) Q.push( “dog” ) front back animal_parade_queue back
Queue Model—FIFO Q.pop(); Q.push( “eel” ); Q.pop(); front animal_parade_queue back
Uses of ADT Queue Buffers Breadth first search Simulations Producer-Consumer Problems
Depth First Search—Backtracking Problem Discover a path from start to goal Solution Go deep If there is an unvisited neighbor, go there Backtrack Retreat along the path to find an unvisited neighbor Outcome If there is a path from start to goal, DFS finds one such path start goal
Depth First Search—Backtracking (2) Stack start goal 1 Push
Depth First Search—Backtracking (3) Stack start goal 2 1 Push
Depth First Search—Backtracking (4) Stack start goal Push
Depth First Search—Backtracking (5) Stack start goal Push
Depth First Search—Backtracking (6) Stack start goal Push
Depth First Search—Backtracking (7) Stack start goal Push Pop
Depth First Search—Backtracking (8) Stack start goal Push Pop
Depth First Search—Backtracking (9) Stack start goal 2 1 Push Pop
Depth First Search—Backtracking (10) Stack start goal 1 Push Pop
Depth First Search—Backtracking (11) Stack start goal 3 1 Push
Depth First Search—Backtracking (12) Stack start goal Push
Depth First Search—Backtracking (13) Stack start goal Push
DFS Implementation DFS() { stack S; // mark the start location as visited S.push(start); while (S is not empty) { t = S.top(); if (t == goal) Success(S); if (// t has unvisited neighbors) { // choose an unvisited neighbor n // mark n visited; S.push(n); } else { BackTrack(S); } Failure(S); }
DFS Implementation (2) BackTrack(S) { while (!S.empty() && S.top() has no unvisited neighbors) { S.pop(); } Success(S) { // print success while (!S.empty()) { output(S.top()); S.pop(); } Failure(S) { // print failure while (!S.empty()) { S.pop(); }
Breadth First Search Problem Find a shortest path from start to goal start goal
Breadth First Search (2) Queue start goal 1 push
Breadth First Search (3) Queue start goal pop
Breadth First Search (4) Queue start goal 234 pop
Breadth First Search (5) Queue start goal pop 34
Breadth First Search (6) Queue start goal 3456 push
Breadth First Search (7) Queue start goal 456 Pop
Breadth First Search (8) Queue start goal Push
Breadth First Search (9) Queue start goal 5678 Pop
Breadth First Search (10) Queue start goal 678 Pop
Breadth First Search (11) Queue start goal 78 Pop
Breadth First Search (12) Queue start goal 789 Push
Breadth First Search (13) Queue start goal 89 Pop
Breadth First Search (14) Queue start goal 8910 Push
BFS Implementation BFS { queue Q; // mark the start location as visited Q.push(start); while (Q is not empty) { t = Q.front(); for (// each unvisited neighbor n) { Q.push(n); if (n == goal) Success(S); } Q.pop(); } Failure(Q); }
Evaluating Postfix Expressions Postfix expressions: operands precede operator Tokens: atomics of expressions, either operator or operand Example: z = 25 + x*(y – 5) Tokens: z, =, 25, +, x, *, (, y, -, 5, )
Evaluating Postfix Expressions (2) Evaluation algorithm: Use stack of tokens Repeat If operand, push onto stack If operator pop operands off the stack evaluate operator on operands push result onto stack Until expression is read Return top of stack
Evaluating Postfix Expressions (3) Most CPUs have hardware support for this algorithm Translation from infix to postfix also uses a stack (software)
Evaluating Postfix Expressions (4) Original expression: 1 + (2 + 3) * Evaluate: * + 5 +
Evaluating Postfix Expressions (5) Input: * Push(1) 1
Evaluating Postfix Expressions (6) Input: * Push(2) 2 1
Evaluating Postfix Expressions (7) Input: * Push(3) 3 2 1
Evaluating Postfix Expressions (8) Input: + 4 * Pop() == 3 Pop() == 2 1
Evaluating Postfix Expressions (9) Input: + 4 * Push(2 + 3) 5 1
Evaluating Postfix Expressions (10) Input: 4 * Push(4) 4 5 1
Evaluating Postfix Expressions (11) Input: * Pop() == 4 Pop() == 5 1
Evaluating Postfix Expressions (12) Input: * Push(5 * 4) 20 1
Evaluating Postfix Expressions (13) Input: Pop() == 20 Pop() == 1
Evaluating Postfix Expressions (14) Input: Push(1 + 20) 21
Evaluating Postfix Expressions (15) Input: 5 + Push(5) 5 21
Evaluating Postfix Expressions (16) Input: + Pop() == 21 Pop() == 5
Evaluating Postfix Expressions (17) Input: + Push(21 + 5) 26
Evaluating Postfix Expressions (18) Input: Pop() == 26
Postfix Evaluation Implementation Evaluate(postfix expression) { // use stack of tokens; while(// expression is not empty) { t = next token; if (t is operand) { // push onto stack } else { // pop operands for t off stack // evaluate t on these operands // push result onto stack } // return top of stack }
Reading Exercise How to use stack to Balance brackets Convert infix to postfix
Runtime Stack Runtime environment Static Executable code Global variables Stack Push for each function call Pop for each function return Heap Dynamic new and delete static stack heap program memory
Recursion Order 1: function calls itself Order 2: f() calls g(), and g() calls f() Facilitated by stack
Adaptor Class Adapts the public interface of another class Adaptee: the class being used Adaptor: the new class being defined Uses protected object of the adaptee type Uses the adaptee’s methods to define adaptor methods Stack and Queue implemented via adaptor classes
Stack Adaptor Requirements Stack push() pop() top() empty() size() Can use List, Deque
Queue Adaptor Requirements Queue push() pop () front() back() empty() size() Can use List, Deque
Class Stack template class Stack { protected: Container c; public: void push(const T & x) { c.push_back(x); } void pop() { c.pop_back(); } T top() const { return c.back(); } int empty() const { return c.empty(); } unsigned int size() const { return c.size(); } void clear() { c.clear(); } };
Declarations Stack > floatStack; Stack > intStack;
Class Queue template class Queue { protected: Container c; public: void push(const T & x) { c.push_back(x); } void pop() { c.pop_front(); } T front() const { return c.front(); } int empty() const { return c.empty(); } unsigned int size() const { return c.size(); } void clear() { c.clear(); } };