lecture 6: stacks
DESCRIPTION
Lecture 6: Stacks. The Abstract Data Type. Specifications of an abstract data type for a particular problem Can emerge during the design of the problem’s solution Examples readAndCorrect algorithm displayBackward algorithm. Developing an ADT During the Design of a Solution. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/1.jpg)
Lecture 6: Stacks
1
![Page 2: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/2.jpg)
2
The Abstract Data Type
• Specifications of an abstract data type for a particular problem– Can emerge during the design of the problem’s
solution– Examples
•readAndCorrect algorithm•displayBackward algorithm
![Page 3: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/3.jpg)
3
Developing an ADT During the Design of a Solution
• ADT stack operations– Create an empty stack– Destroy a stack– Determine whether a stack is empty– Add a new item to the stack– Remove the item that was added most recently– Retrieve the item that was added most recently
![Page 4: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/4.jpg)
4
Developing an ADT During the Design of a Solution
Figure 6-1
Stack of cafeteria dishes
• A stack– Last-in, first-out (LIFO)
property• The last item placed on the
stack will be the first item removed
– Analogy• A stack of dishes in a
cafeteria
![Page 5: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/5.jpg)
5
Refining the Definition of the ADT Stack
• Operation Contract for the ADT StackisEmpty():boolean {query}
push(in newItem:StackItemType)
throw StackException
pop() throw StackException
pop(out stackTop:StackItemType)
throw StackException
getTop(out stackTop:StackItemType) {query}
throw StackException
![Page 6: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/6.jpg)
6
Implementations of the ADT Stack
• The ADT stack can be implemented using – An array– A linked list– The ADT list
• All three implementations use a StackException class to handle possible exceptions
![Page 7: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/7.jpg)
7
An Array-Based Implementation of the ADT Stack
• Private data fields– An array of items of type StackItemType– The index top to the top item
• Compiler-generated destructor and copy constructor
Figure 6-5
An array-based implementation
![Page 8: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/8.jpg)
• const int MAX_STACK = 20;
• typedef int StackItemType;
• class Stack
• {
• public:
• Stack(); // default constructor
• bool isEmpty() const;
• void push(StackItemType newItem) ;
• void pop() ;
• void pop(StackItemType& stackTop);
• void getTop(StackItemType& stackTop) const;
• private:
• StackItemType items[MAX_STACK]; // array of stack items
• int top; // index to top of stack
• }; // end class
![Page 9: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/9.jpg)
• Stack::Stack(): top(-1)
• {
• }; // end default constructor
• bool Stack::isEmpty() const
• {
• return top < 0;
• }; // end isEmpty
![Page 10: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/10.jpg)
• void Stack::push(StackItemType newItem) throw(StackException)
• {// if stack has no more room for another item
• if (top >= MAX_STACK-1)
• throw StackException("StackException: stack full on push");
• else
• { ++top;
• items[top] = newItem;
• } // end if
• }; // end push
• void Stack::pop() throw(StackException)
• {
• if (isEmpty())
• throw StackException("StackException: stack empty on pop");
• else
• --top; // stack is not empty; pop top
• }; // end pop10
![Page 11: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/11.jpg)
• void Stack::pop(StackItemType& stackTop) throw(StackException)
• {
• if (isEmpty())
• throw StackException("StackException: stack empty on pop");
• else
• { // stack is not empty; retrieve top
• stackTop = items[top];
• --top; // pop top
• } // end if
• }; // end pop
• void Stack::getTop(StackItemType& stackTop) const throw(StackException)
• {
• if (isEmpty())
• throw StackException("StackException: stack empty on getTop");
• else
• // stack is not empty; retrieve top
• stackTop = items[top];
• }; // end getTop11
![Page 12: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/12.jpg)
• int main()
• {
• StackItemType anItem;
• Stack aStack;
• for (int i = 0; i< 10; i++)
• {anItem = i*10;
• aStack.push(anItem); // push it onto stack
• }
• while (!aStack.isEmpty())
• { aStack.getTop(anItem);
• cout <<anItem<<endl;
• aStack.pop();
• }
• return 0;
• }//ex6-1.cpp
12
![Page 13: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/13.jpg)
13
Implementations of the ADT Stack
Figure 6-4
Implementations of the ADT stack that use (a) an array; (b) a linked list; (c) an ADT list
![Page 14: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/14.jpg)
14
A Pointer-Based Implementation of the ADT Stack
• A pointer-based implementation– Enables the stack to grow and shrink
dynamically
• topPtr is a pointer to the head of a linked list of items
• A copy constructor and destructor must be supplied
Figure 6-6 A pointer-based implementation
![Page 15: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/15.jpg)
• class Stack
• {public:
• //…
• Stack(const Stack& aStack);
• //…
• ~Stack(); //Destructor;
• private:
• struct StackNode // a node on the stack
• { StackItemType item; // a data item on the stack
• StackNode *next; // pointer to next node
• }; // end struct
• StackNode *topPtr; // pointer to first node in the stack
• }; // end class
15
Pointer-based Stack
![Page 16: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/16.jpg)
• Stack::Stack() : topPtr(NULL)• {} // end default constructor• Stack::Stack(const Stack& aStack)• { if (aStack.topPtr == NULL)• topPtr = NULL; // original list is empty• else• { // copy first node• topPtr = new StackNode;• topPtr->item = aStack.topPtr->item;• // copy rest of list• StackNode *newPtr = topPtr; // new list pointer• for (StackNode *origPtr = aStack.topPtr->next; origPtr != NULL;• origPtr = origPtr->next)• { newPtr->next = new StackNode;• newPtr = newPtr->next;• newPtr->item = origPtr->item;• } // end for• newPtr->next = NULL;• } // end if• } // end copy constructor 16
![Page 17: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/17.jpg)
• Stack::~Stack()
• {while (!isEmpty()) pop(); } // Assertion: topPtr == NULL
• bool Stack::isEmpty() const
• { return topPtr == NULL; } // end isEmpty
• void Stack::push(StackItemType newItem)
• { // create a new node
• StackNode *newPtr = new StackNode;
• // set data portion of new node
• newPtr->item = newItem;
• // insert the new node
• newPtr->next = topPtr;
• topPtr = newPtr;
• } // end push
17
![Page 18: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/18.jpg)
• void Stack::pop() throw(StackException)
• {
• if (isEmpty())
• throw StackException("StackException: stack empty on pop");
• else
• { // stack is not empty; delete top
• StackNode *temp = topPtr;
• topPtr = topPtr->next;
• // return deleted node to system
• temp->next = NULL; // safeguard
• delete temp;
• } // end if
• } // end pop
18
![Page 19: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/19.jpg)
• void Stack::pop(StackItemType& stackTop) throw(StackException)
• {if (isEmpty()) throw StackException("StackException: stack empty on pop");
• else
• { // stack is not empty; retrieve and delete top
• stackTop = topPtr->item;
• StackNode *temp = topPtr;
• topPtr = topPtr->next;
• temp->next = NULL; // safeguard
• delete temp; // return deleted node to system
• } // end if
• } // end pop
• void Stack::getTop(StackItemType& stackTop) const throw(StackException)
• { if (isEmpty()) throw StackException("StackException: stack empty on getTop");
• else // stack is not empty; retrieve top
• stackTop = topPtr->item;
• } // end getTop
• //ex6-2.cpp 19
![Page 20: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/20.jpg)
20
An Implementation That Uses the ADT List
• The ADT list can represent the items in a stack• Let the item in position 1 of the list be the top
– push(newItem)• insert(1, newItem)
– pop() • remove(1)
– getTop(stackTop) • retrieve(1, stackTop)
![Page 21: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/21.jpg)
21
An Implementation That Uses the ADT List
Figure 6-7
An implementation that uses the ADT list
![Page 22: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/22.jpg)
22
Comparing Implementations
• Fixed size versus dynamic size– A statically allocated array-based implementation
• Fixed-size stack that can get full
• Prevents the push operation from adding an item to the stack, if the array is full
– A dynamically allocated array-based implementation or a pointer-based implementation
• No size restriction on the stack
![Page 23: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/23.jpg)
23
Comparing Implementations
• A pointer-based implementation vs. one that uses a pointer-based implementation of the ADT list– Pointer-based implementation is more efficient– ADT list approach reuses an already
implemented class• Much simpler to write
• Saves programming time
![Page 24: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/24.jpg)
List Based Stack
• Stack
• {public:
• //…
• private:
• List aList; // list of stack items
• };// others are the same as the Pointer-based
24
![Page 25: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/25.jpg)
• Stack::Stack()
• { } // end default constructor
• Stack::Stack(const Stack& aStack): aList(aStack.aList)
• { } // end copy constructor
• Stack::~Stack()
• { } // end destructor
• bool Stack::isEmpty() const
• {
• return aList.isEmpty();
• } // end isEmpty
25
![Page 26: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/26.jpg)
• void Stack::push(StackItemType newItem) throw(StackException)
• { try {
• aList.insert(1, newItem);
• } // end try
• catch (ListException e)
• { throw StackException("StackException: cannot push item");
• } // end catch
• } // end push
• void Stack::pop() throw(StackException)
• { try {
• aList.remove(1);
• } // end try
• catch (ListIndexOutOfRangeException e)
• { throw StackException("StackException: stack empty on pop");
• } // end catch
• } // end pop26
![Page 27: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/27.jpg)
• void Stack::pop(StackItemType& stackTop) throw(StackException)• { try {• aList.retrieve(1, stackTop);• aList.remove(1);• } // end try• catch (ListIndexOutOfRangeException e)• { throw StackException("StackException: stack empty on pop");• } // end catch• } // end pop
• void Stack::getTop(StackItemType& stackTop) const throw(StackException)• { try {• aList.retrieve(1, stackTop);• } // end try• catch (ListIndexOutOfRangeException e)• { throw StackException("StackException: stack empty on getTop");• } // end catch• } // end getTop• //ex6-3.cpp
27
![Page 28: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/28.jpg)
28
The STL Class stack
• Provides a size function • Has two data type parameters
– T, the data type for the stack items– Container, the container class that the STL uses in
its implementation of the stack
• Uses the keyword explicit in the constructor’s declaration to prevent use of the assignment operator to invoke the constructor
![Page 29: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/29.jpg)
• #include <iostream>• #include <stack>• using namespace std;• int main()• { stack<int> aStack;• int item;• // Right now, the stack is empty• if (aStack.empty())• cout << "The stack is empty." << endl;• for (int j = 0; j < 5; j++)• aStack.push(j); // places items on top of stack• while (!aStack.empty())• { cout << aStack.top() << endl;• aStack.pop();• } // end while• return 0;• } // end main• //ex6-4.cpp 29
![Page 30: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/30.jpg)
30
Using the ADT Stack in a Solution
• A program can use a stack independently of the stack’s implementation– displayBackward algorithm can be refined
using stack operations• Use axioms to define an ADT stack formally
– Example: Specify that the last item inserted is the first item to be removed(aStack.push(newItem)).pop()= aStack
![Page 31: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/31.jpg)
31
Checking for Balanced Braces
• A stack can be used to verify whether a program contains balanced braces– An example of balanced braces
abc{defg{ijk}{l{mn}}op}qr
– An example of unbalanced bracesabc{def}}{ghij{kl}m
![Page 32: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/32.jpg)
32
Checking for Balanced Braces
• Requirements for balanced braces– Each time you encounter a “}”, it matches an
already encountered “{”– When you reach the end of the string, you have
matched each “{”
![Page 33: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/33.jpg)
33
Checking for Balanced Braces
Figure 6-3
Traces of the algorithm that checks for balanced braces
![Page 34: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/34.jpg)
34
bool balanced (string str)• { int index=0;• Stack S;• while (str [index]!= '\0') {• if (str[index] == ‘{' )• S.push(‘{');• else if(str[index] == ‘}' ) {• if(!S.isEmpty( )) S.pop( );• else return 0; • }• ++index; // next character• }• return (S.isEmpty( ));• }//ex6-5.cpp
![Page 35: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/35.jpg)
35
We define a language L as follows:
L = {w$w’| w is a character string that does not contain a $ sign. w’ is the reverse of w.}
PALINDROMES
EXAMPLES:
A$A AB$BA ABA$ABA // in language
Counter Examples:
A$B A$B$B$A A$BA //not in language
Basic Idea: Keep pushing characters onto a stack until you see a $. Then keep popping and reading, and compare those characters. Return FALSE if a popped character is different from a read character. Return TRUE if the stack becomes empty and the end of the string is found at the same time.
Recognizing Languages
![Page 36: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/36.jpg)
36bool palindrome (string str)
• { int index=0; Stack S;
• while (str[index] != '$') {
• if (str[index] == '\0') return false;
• S.push(str[index]);
• ++index; }
• ++index; char ch;
• while (str[index] != '\0') {
• if (S.isEmpty( )) return false;
• S.getTop(ch);
• if (ch != str[index] ) return false;
• S.pop( );
• ++index; }
• if (S.isEmpty( )) return true; // should be!
• else return false;
• } //ex6-5.cpp
![Page 37: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/37.jpg)
37
Evaluating Postfix Expressions:
Given is a postfix expression, compute its value.
2 * (3 + 4) (infix)
2 3 4 + * (corresponding postfix)
2 * (3 + 4) -> 14
2 3 4 + * -> 14
![Page 38: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/38.jpg)
38
Basic Idea:
We use a stack again, but this time we put the NUMBERS onto it. Every time we see a number, we push it. Every time we see an operator, we pop off two numbers, apply the operator, and push the result back onto the stack.
2 3 4 + *2 ... ... Push 2 on the stack3 ... ... Push 3 on the stack4 ... ... Push 4 on the stack+ ... ... Pop off 4; Pop off 3;
add 3 and 4; (ORDER!)Push 7 on stack.
* ... ... Pop off 7; Pop off 2;Multiply 2 and 7; Push14 back on the stack.
![Page 39: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/39.jpg)
39
Now the same example using the abstract data type.
S.Push(2)
S.Push(3)
S.Push(4)
y = S.GetStackTop()
S.Pop()
x = S.GetStackTop()
S.Pop()
z = x + y
S.Push(z)
y = S.GetStackTop()
S.Pop()
x = S.GetStackTop()
S.Pop()
z = x * y
S.Push(z)
![Page 40: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/40.jpg)
40For the program we make a number of simplifying assumptions: No error checking; No unary operators; Only +,-,*,/ as operators; and Only digit 1-9 as
operands int evaluate (string str)
• {Stack S; int x, y, z;
• for ( int index =0; index< str.length(); ++index) { // look at each char
– if (( str[index]=='+' )||(str[index] == '-')||(str[index] == '*')||(str[index] == '/')) {S.getTop(y); S.pop( );
• S.getTop(x); S.pop( );
• switch (str[index]){case '+': z = x + y; break; case '-': z = x-y; break;
• case '*': z = x*y; break; case '/': z = x/y; break;
• } ; S.push(z);
• }
else S.push(str[index]-'0');
• }
• S.getTop(z); return z;
• }
![Page 41: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/41.jpg)
41
Converting Infix to Postfix
(Complicated)This uses a stack again, but this time it stores the operators and open
parentheses, as opposed to the operands.
The result is stored in an array “PE”, the postfix expression.
Algorithm
1. If an operand appears in the input stream, then append it to the PE array.
2. If a “(“ appears in the input stream, then push it onto the stack.
3. If a “)” appears in the input stream, then pop off elements from the stack and append them to the PE array until an open parenthesis is found on the stack. Pop off and discard the (
![Page 42: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/42.jpg)
42
4. If an operator appears in the input stream, then: IF the stack is NOT EMPTY then pop off operators of greater or equal precedence from the stack and append them to PE, until:
a) either: the stack is empty
b) or: you find an “(“ on the stack
c) or: you find an operator of lower precedenceThen push the new operator on the stack.
5. When you reach the end of the input, then pop off all operators from the stack and append them to the end of PE.
![Page 43: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/43.jpg)
43Now we will show an example of how to actually do this. We convert:
A - (B + C * D) / E
We will show the stack top on the RIGHT.
CH= A S= PE= A 1.CH= - S= - PE= A 4.d)CH= ( S= -( PE= A 2.CH= B S= -( PE= AB 1.CH= + S= -(+ PE= AB 4.b)CH= C S= -(+ PE= ABC 1.CH= * S= -(+* PE= ABC 4.c)
CH= D S= -(+* PE= ABCD 1.CH= ) S= -(+ PE= ABCD* 3.
S= -( PE= ABCD*+ 3.S= - PE= ABCD*+ 3.
CH= / S= -/ PE= ABCD*+ 4.d)CH= E S= -/ PE= ABCD*+E 1.
S= - PE= ABCD*+E/ 5.S= PE= ABCD*+E/- 5.
![Page 44: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/44.jpg)
44Why does this work? This algorithm is based on the following observations:1) Operands stay in the same order.
A+B becomes AB+ and NOT BA+
2) Operators move only to the right, never to the left, relative to the operands.
A+B ---> AB+ + moved to the right of B.
3) Postfix expressions don’t need parenthesis.
![Page 45: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/45.jpg)
• string infixToPostfix (string str)
• {Stack S; string result; int y;
• for ( int index =0; index< str.length(); ++index) {
• // look at each char
• switch (str[index]) {
• case '(':S.push (str[index]); break;
• case ')':
• if (!S.isEmpty()){ S.pop(y);
• while (char (y) !='(') {result+=char(y); S.pop(y); };
• }
• break;
![Page 46: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/46.jpg)
• case '+': case '-': case '*': case '/':
• if (!S.isEmpty()){S.getTop(y);
• while ((!S.isEmpty())&& (char(y)!='(') &&(pre(str[index])<= pre(y)))
• { result+=char(y);S.pop();S.getTop(y);}}
• S.push (str[index]);
• break;
• default:
• if (str[index]<='Z'&&str[index]>='A')||(str[index]<='z'&&str[index]>='a'))
• result+=str[index];
• }
• }
![Page 47: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/47.jpg)
• while (!S.isEmpty()) {S.pop(y);
• if ((char(y) == '+')||(char(y) == '-')||(char(y) == '*')||(char(y) == '/'))result+=char(y);
• else return "Error!";
• }
• return result;
• }
![Page 48: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/48.jpg)
48
SearchThis section uses a structure called a graph that will be covered in more detail much later in the class.
Given is the following problem:
There is a map of cities, and there is a flight plan that describes all connections between cities. Then you are given two specific cities, A and B and asked whether you can fly from A to B.
Note: In a real flight plan you can’t be sure that there is a flight from B to A. We will use examples that make this assumption. In fact, there will be “dead-end cities” with no flights leaving. (Flights in, No flights out)
Of course this problem uses a stack, but we start with the representation of the map.
![Page 49: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/49.jpg)
49
Example:
Y Z
W S T
Q X R P
![Page 50: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/50.jpg)
50
How do we represent this “graph” in the computer? There are two possibilities, but for now we will learn only one: The Adjacency List.
An adjacency list is really an ARRAY OF LINKED LISTS. For every city there is one element in the array. This element is a pointer to a linked list. Every element of the linked list contains the name of ONE NEIGHBORING
CITY.
![Page 51: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/51.jpg)
51
Note:
The linked list from the array position P to R and W does Not imply any order. It just says that there is a flight from P to W and there is a flight from P to R.
We need one more data structure, a boolean array that “remembers” if we already visited a city.
P Q R S T W X Y Z
R X X T W S R
ZYW
NULL NULL
NULLNULLNULL
![Page 52: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/52.jpg)
52Back to the problem:We assume that there are three files:Cityfile...
A file of cities, in alphabetical order, that are known to all. If there is no flight from or to a city, it is just not mentioned here.
Flightfile... This is the actual flight plan. Each line contains a pair of cities, and such a line means that there is a flight from the first city to the second city.
Requestfile...This looks exactly like the Flightfile, but it stands for a request.
![Page 53: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/53.jpg)
53For the simplest version we want only answer:
“you can get there from here,” or “you cannot get there from here.”
We use a backtrack search to find the path. If necessary we search “exhaustively,” which means we try every possible path. Let’s call the origin city O, and the destination city D. Either we find a path, or we conclude that no path exists.
Basic approach: Look at a neighbor of O. If the neighbor is D, then we are
done. If this neighbor is not D, say it is C1, then we look at a neighbor of C1. If the neighbor of C1 is D, we are done, etc.
![Page 54: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/54.jpg)
54Now comes the backtrack part: In our hypothetical flight plan, there are cities where no flights leave at all(!) If we reach such a city, then we have to return to the previous choice and make another selection. For that I need to store the previous selection, and that is what the stack is used for.
Invariant: The stack contains at every moment the cities on a trip from O to the current city. O is at the bottom of the stack. By popping off the top element, I can return to the previous city.
After I popped a city off the stack, how do I make sure that I don’t go there again? That’s where the “visited” array is used.
![Page 55: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/55.jpg)
55
Important notes:
1. The described search algorithm does not define at all in what order we are visiting cities. In practice we use the order in the adjacency list.
2. The resultant path might be a very bad one. There might exist a direct flight, and I might choose a much longer path instead.
3. The result will, however, never contain a circle. The “visited” array protects me from that.
Now comes the basic algorithm.
![Page 56: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/56.jpg)
56
search(O,D)
S.Push(O); visited[O] = TRUE;
while ((!S.StackIsEmpty( ))&&
(S.GetStackTop( ) != D) {
C1 = S.GetStackTop( );
if (/*there are no flights from C1 to any unvisited city*/) S.Pop( );
else
// select any unvisited neighbor C of C1
S.Push(C); visited[C] = TRUE
}
}
Example: In the previous map, how do we get from P to Z?
We start with a stack containing P. As before, the top is at the right.
S= P
![Page 57: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/57.jpg)
Example: P->Z 44
Y Z
W S T
Q X R P
S = P
S = PR
S = PRX
S = PR
S = P
S = PW
S = PWS
S = PWST
S = PWS
S = PW
S = PWY
S = PWYZEx6-6.cpp
![Page 58: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/58.jpg)
58
The relationship between stacks and recursion:
We could have solved the same search problem in a recursive manner. In fact, this is always true. A recursive program can be modeled by a program using a stack. There is a deeper reason for this: The INTERNAL
IMPLEMENTATION of recursion in C++ uses a stack.
![Page 59: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/59.jpg)
59
RecursiveSearch(O,D)
visited[O] = TRUE
if (O == D)
// report success
else
for ( C = all neighbors of O )
RecursiveSearch(C,D)
Note that this is very rough. The FOR loop would go on after we already were successful.
![Page 60: Lecture 6: Stacks](https://reader036.vdocuments.mx/reader036/viewer/2022070405/56813f65550346895daa39b1/html5/thumbnails/60.jpg)
60
Summary
• ADT stack operations have a last-in, first-out (LIFO) behavior
• Stack applications– Algorithms that operate on algebraic
expressions – Flight maps
• A strong relationship exists between recursion and stacks