1 stacks (walls & mirrors - chapter 6). 2 overview the adt stack array implementation of a stack...

56
1 Stacks (Walls & Mirrors - Chapter 6)

Post on 21-Dec-2015

228 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

1

Stacks

(Walls & Mirrors - Chapter 6)

Page 2: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

2

Overview

• The ADT Stack

• Array Implementation of a Stack

• Linked-List Implementation of a Stack

• Application Domain: Algebraic Expressions

• Application Domain: Search

Page 3: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

3

The ADT Stack

• A stack is a linear list, for which all insertions and deletions occur at one end of the list. Stacks exhibit a Last In First Out (LIFO) property.

• This is like a cafeteria tray (or plate) dispenser.

IN OUT

Page 4: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

4

The ADT Stack (Cont’d.)

Recall, that an abstract data type (ADT) is a type of data, defined by the programmer, where the implementation details are hidden from the user, and access to the data is provided through an interface to a specific set of operations.

Page 5: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

5

The ADT Stack (Cont’d.)

• For an ADT stack, these operations include:

– Create an empty stack

– Destroy a stack

– Determine whether a stack is empty

– Add a new item to the stack

– Remove the item added most recently

– Retrieve a copy of the item added most recently

• As long as these operations are supported, you don’t need to be concerned with whether the stack is implemented as an array, a linked list, or something else.

Page 6: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

6

ADT Stack: Public Member Functions

Stack( );

is the default constructor, which creates a new, empty stack.

Stack( const Stack &oStack );

is the copy constructor, which makes a copy of oStack.

~Stack( );

is the destructor, which destroys a stack.

bool isEmpty( ) const;

returns true if the stack is empty, otherwise returns false.

Page 7: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

7

ADT Stack: Public Member Functions

bool push( StackItemType newItem );

adds newItem to the top of a stack. Returns true if push succeeds, otherwise returns false.

bool pop( );

removes the item at the top of a stack. Returns true if pop succeeds, otherwise returns false.

bool pop( StackItemType &stackTop );

removes the item at the top of a stack and returns it in stackTop. Returns true if pop succeeds, otherwise returns false.

Page 8: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

8

ADT Stack: Public Member Functions

bool getTop( StackItemType &stackTop ) const;

retrieves a copy of the item at the top of a stack, leaving the stack unchanged. Returns true if getTop succeeds, otherwise returns false.

Page 9: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

9

ADT Stack: Array Implementation

const int MAX_STACK = 20;// maximum Stack size

typedef int StackItemType; // items in Stack are int’s

class Stack

{

public:

// declarations of public member functions

private:

StackItemType items[MAX_STACK]; // array of Stack items

int top; // index to top of Stack

};

Page 10: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

10

ADT Stack: Member Function Definitions

Stack::Stack( ) : top( -1 ) { } // default constructor, which

// creates a new Stack and

// initializes top to -1

Stack::Stack( const Stack &oStack ) // copy constructor,

: top( oStack.top ) // which copies oStack

{ // to a new Stack

for( int i = 0; i <= oStack.top; i++ )

items[i] = oStack.items[i];

}

Page 11: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

11

ADT Stack: Member Function Definitions

// destructor

Stack::~Stack( ) { }

// returns true if Stack is empty, otherwise returns false

bool Stack::isEmpty( ) const

{

return top < 0;

}

Page 12: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

12

ADT Stack: Member Function Definitions

// adds newItem to the top of a Stack. Returns true if

// add succeeds, otherwise returns false.

bool Stack::push( StackItemType newItem )

{

if( top >= MAX_STACK - 1 ) return false;

items[ ++top ] = newItem;

return true;

}

Page 13: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

13

ADT Stack: Member Function Definitions

// removes the item at the top of a Stack. Returns true if

// removal succeeds, otherwise returns false.

bool Stack::pop( )

{

if( isEmpty( ) ) return false;

top--;

return true;

}

Page 14: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

14

ADT Stack: Member Function Definitions

// removes the item at the top of a Stack and returns it in

// stackTop. Returns true if removal succeeds, otherwise

// returns false.

bool Stack::pop( StackItemType &stackTop )

{

if( isEmpty( ) ) return false;

stackTop = items[top];

top--;

return true;

}

Page 15: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

15

ADT Stack: Member Function Definitions

// retrieves a copy of the item at the top of a Stack and returns

// it in stackTop. Returns true if retrieval succeeds

// otherwise returns false.

bool Stack::getTop( StackItemType &stackTop ) const

{

if( isEmpty( ) ) return false;

stackTop = items[top];

return true;

}

Page 16: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

16

ADT Stack: Linked-List Implementationtypedef int StackItemType; // items in Stack are int’s

class Stack

{ public:

// declarations of public member functions - same as for array!

private:

struct StackNode // linked-list of items in Stack

{

StackItemType item;

StackNode *next;

};

StackNode *topPtr; // pointer to top of Stack

};

Page 17: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

17

ADT Stack: Member Function Definitions

// default constructor, which creates a new Stack and // initializes topPtr to NULL

Stack::Stack( ) : topPtr( NULL ) { }

Page 18: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

18

ADT Stack: Member Function Definitions

Stack::Stack( const Stack &oStack ) // copy constructor,{ // which copies oStack if( oStack.topPtr = = NULL ) // to a new Stack topPtr = NULL; else

{ // copy top of Stack

topPtr = new StackNode; // assert is true if

assert( topPtr != NULL ); // allocation succeeds

topPtr -> item = oStack.topPtr -> item;

// copy rest of Stack }}

Page 19: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

19

ADT Stack: Member Function Definitions

// copy rest of Stack

StackNode *pnew = topPtr;

for( StackNode *porig = oStack.topPtr -> next;

porig != NULL; porig = porig -> next )

{ pnew -> next = new StackNode;

assert( pnew -> next != NULL ); // assert is true if

pnew = pnew -> next; // allocation succeeds

pnew -> item = porig -> item;

}

pnew -> next = NULL;

Page 20: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

20

ADT Stack: Member Function Definitions

// destructor pops Stack until empty

Stack::~Stack( ){ while( pop( ) );}

// returns true if Stack is empty, otherwise returns false

bool Stack::isEmpty( ) const{ return topPtr = = NULL;}

Page 21: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

21

ADT Stack: Member Function Definitions

// adds newItem to the top of a Stack. Returns true if

// add succeeds, otherwise returns false.

bool Stack::push( StackItemType newItem ){

StackNode *pnode = new StackNode;

if( pnode = = NULL ) return false;

pnode -> item = newItem;

pnode -> next = topPtr;

topPtr = pnode;

return true;}

Page 22: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

22

ADT Stack: Member Function Definitions

// removes the item at the top of a Stack. Returns true if// removal succeeds, otherwise returns false.

bool Stack::pop( )

{

if( isEmpty( ) ) return false;

StackNode *pnode = topPtr;

topPtr = topPtr -> next;

pnode -> next = NULL;

delete pnode; // removed node is deallocated

return true;

}

Page 23: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

23

ADT Stack: Member Function Definitions

// removes the item at the top of a Stack and returns it in// stackTop. Returns true if removal succeeds, otherwise // returns false.

bool Stack::pop( StackItemType &stackTop )

{ if( isEmpty( ) ) return false;

stackTop = topPtr -> item;

StackNode *pnode = topPtr;

topPtr = topPtr -> next;

pnode -> next = NULL;

delete pnode; // removed node is deallocated

return true;

}

Page 24: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

24

ADT Stack: Member Function Definitions

// retrieves the item at the top of a Stack and returns it in// stackTop. Returns true if retrieval succeeds, otherwise // returns false.

bool Stack::getTop( StackItemType &stackTop ) const

{

if( isEmpty( ) ) return false;

stackTop = topPtr -> item;

return true;

}

Page 25: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

25

Application: Recognizing Balanced Parentheses

Problem: Determine whether the parentheses in a given string are balanced.

Examples:

Balanced Not Balanced

( a b ) ( c d ) ( a b

( ( a b c d ) ) ( a b ) )

( ( a b ) ( c d ) ) ) a b (

Page 26: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

26

Recognizing Balanced Parentheses

Strategy:

• Scan a string, pushing each “(” onto a stack.

• When a “)” is found, pop one “(” from the stack.

• The parentheses are balanced if

– “(” can be popped from the stack for every “)” found, and

– the stack is empty when the entire string has been processed.

Page 27: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

27

Recognizing Balanced Parentheses

typedef char StackItemType; // returns true if str[ ] has

bool isBalanced( const char str[ ] ) // balanced parentheses,

{ // else returns false

Stack parendStack; bool match = true;

for( char *pstr = str; match && *pstr != ‘\0’; pstr++ )

{ if( *pstr = = ‘(’ )

parendStack.push( ‘(’ );

else if( *pstr = = ‘)’ )

{ match = parendStack.pop( ); } } return match && parendStack.isEmpty( );}

Page 28: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

28

Application: Recognizing Strings in a Language

Problem: Define a recognizer for the following language:

{ w$wR : w is a string of characters that does not contain ‘$’,

wR is the reverse of w }

Examples:

In Language Not In Language

A$A A$B

AB$BA A$B$B$A

ABC$CBA A$BA

Page 29: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

29

Recognizing Strings in a Language

Strategy:

• Scan a string, pushing each character onto a stack until ‘$’ is found.

• When ‘$’ is found, skip it. For each character remaining in the string, pop a character from the stack and compare.

• The string is in { w$wR } if

– each character remaining in the string matches, in order, a character popped from the stack, and

– the stack is empty when the entire string has been processed.

Page 30: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

30

Recognizing Strings in a Language

typedef char StackItemType;

bool inLanguage( const char str[ ] )

{

Stack charStack;

// push chars from str[ ] onto charStack until ‘$’ is found

// skip over ‘$’

// match remaining chars in str[ ] with those on charStack

return charStack.isEmpty( );

}

Page 31: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

31

Recognizing Strings in a Language

// push chars from str[ ] onto charStack until ‘$’ is found char *pstr;

for( pstr = str; *pstr != ‘$’; pstr++ )

{ if( *pstr = = ‘\0’ ) return false;

charStack.push( *pstr ); }// skip over ‘$’

pstr++;

// match remaining chars in str[ ] with those on charStack

for( char stackTop; *pstr != ‘\0’; pstr++ )

{ if( !charStack.pop( stackTop ) ) return false;

if( stackTop != *pstr ) return false; }

Page 32: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

32

Application: EvaluatingPostfix Expressions

Problem: Compute the value of a given postfix expression.

Examples:

Infix Postfix Value

2 * ( 3 + 4 ) 2 3 4 + * 14

2 * 3 + 4 2 3 * 4 + 10

( 2 + 3 ) * 4 2 3 + 4 * 20

Page 33: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

33

Evaluating Postfix Expressions

Strategy:

• Scan a string, pushing each number onto a stack.

• When an operator is found

– pop two numbers from the stack,

– apply the operator, and

– push the result back onto the stack.

• When the entire string has been processed, the result will be the only thing left on the stack.

Page 34: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

34

Evaluating Postfix Expressions

2 push( 2 ) 23 push( 3 ) 3 2+ pop( arg2 ) 2

pop( arg1 ) emptyresult = arg1 + arg2push( result ) 5

4 push( 4 ) 4 5* pop( arg2 ) 5

pop( arg1 ) emptyresult = arg1 * arg2push( result ) 20

Scan Process Stack (top is leftmost)

Evaluating 2 3 + 4 * :

Page 35: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

35

Evaluating Postfix Expressions

In the C++ program segment that follows, we make the following simplifying assumptions:

• All input is syntactically correct (no error checking)

• The only operators are +, –, *, /

• No unary operators

• Input operands are non-negative, single-digit integers

• However, the value of the processed expression is an integer that may be either positive or negative and contain multiple digits.

Page 36: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

36

Evaluating Postfix Expressions

We also assume that the following functions are available:

• bool isDigit( char chr ) returns true if character chr is a member of the set

{ ‘0’, ‘1, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ },

otherwise returns false.

• int Value( char digit ) returns an integer representing the value of the character digit.

• int Eval( int arg1, char op, int arg2 ) returns an integer representing the value of arg1 op arg2.

Page 37: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

37

Evaluating Postfix Expressions// value of postfix expression in str[ ] is placed on top of intStack

typedef int StackItemType;

Stack intStack; char *pstr; int arg1, arg2;

for( pstr = str; *pstr != ‘\0’; pstr++ )

{

if( isDigit( *pstr ) ) intStack.push( Value( *pstr ) );

else // *pstr is an operator

{ intStack.pop( arg2 );

intStack.pop( arg1 );

intStack.push( Eval( arg1, *pstr, arg2 ) );

}

}

Page 38: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

38

Converting Infix to Postfix: Strategy

Strategy (5 rules):

1) Initialize char postfixExpr[ ] to the empty string. When an operand is found in the input, append it to the end of postfixExpr[ ].

2) When a ‘(’ is found in the input, push it onto a Stack.

3) When a ‘)’ is found in the input, pop operators off the Stack and append them, in order, to the end of postfixExpr[ ], until a matching ‘(’ is popped from the Stack.

Page 39: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

39

Converting Infix to Postfix: Strategy

Strategy (cont’d.):

4) When an operator is found in the input:

a) If the Stack is empty, push the operator onto the Stack.

b) Otherwise, pop operators of greater or equal precedence from the Stack and append them to postfixExpr[ ], stopping when:

• the Stack is empty, or

• a ‘(’ is found on the Stack, or

• an operator of lower precedence is found on the Stack.

Then, push the operator onto the Stack.

Page 40: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

40

Converting Infix to Postfix: Strategy

Strategy (cont’d.):

5) When the end of the input is reached, pop all operators from the Stack and append them, in order, to the end of postfixExpr[ ].

Example:

Use the preceding algorithm to convert the following to postfix:

A – (B + C * D) / E

Page 41: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

41

Infix to Postfix: A – (B + C * D) / E

Step Input Stack(top at left)

postfixExpr[ ] Rule #

1. A A 1 2. – – A 4 a 3. ( ( – A 2 4. B ( – A B 1 5. + + ( – A B 4 b 6. C + ( – A B C 1 7. * * + ( – A B C 4 b 8. D * + ( – A B C D 1 9. ) – A B C D * + 3

Page 42: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

42

Infix to Postfix: A – (B + C * D) / E

Step Input Stack(top at left)

postfixExpr[ ] Rule #

9. ) – A B C D * + 310. / / – A B C D * + 4 b11. E / – A B C D * + E 112. A B C D * + E / – 5

Page 43: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

43

Infix to Postfix: Observations

• Operands stay in the same order:

A + B becomes A B + not B A +

• An operator will move only to the right relative to its operands:

A + B becomes A B + not + A B

• Parentheses are removed

(A + B) * C becomes A B + C *

See Chapter 6 of Walls & Mirrors for detailed pseudocode corresponding to this algorithm

Page 44: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

44

Search for a Path Between Two Cities

Problem: Given the origin and destination of each flight made by an airline, determine whether a sequence of these flights will allow one to travel from a desired origin to a desired destination.

Example:

Q X R P

Y

W S T

Z

Page 45: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

45

Search for a Path Between Two Cities

3 Files Are Provided As Input:

• Cityfile – names of the cities served by the airline.

• Flightfile – pairs of city names, representing the origin and destination of each airline flight.

• Requestfile – one pair of city names, representing a request to fly from some origin to some destination.

Output Either:

• “Desired path exists” or

• “Desired path does not exist”

Page 46: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

46

Search for a Path: Strategy

Strategy: Use backtracking to perform an exhaustive search of all (non-looping) sequences of flights that originate from the desired origin.

We explore the basic idea behind this strategy on the next slide. Let O denote the desired origin and D denote the desired destination.

Page 47: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

47

Search for a Path: Basic Idea1) Select a flight (O C1) originating from O.

2) If C1 = D, we are done: there is a direct flight O D. Otherwise, select a flight (C1 C2).

3) If C2 = D, we are done: there is a path O C1 D. Otherwise, select a flight (C2 C3).

4) Continue in this manner until a city Ck is reached with no departing flights. Backtrack to the city Ck-1 from which we departed to arrive at Ck.

5) Now, select a flight (Ck-1 Cm) originating from Ck-1 that is different from (Ck-1 Ck). If Cm = D, we are done: there is a path O C1 C2 . . . Ck-1 D. Otherwise, select a flight (Cm Cm+1), and continue as above.

Page 48: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

48

Search for a Path: Loop Avoidance

How do we avoid looping (or cycling) through the same cities? In the given example,

how do we avoid a path such as

W S T W S T . . . ?

Q X R P

Y

W S T

Z

Page 49: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

49

Search for a Path: Loop Avoidance

Mark a city when it is visited. When choosing the next city to visit, restrict consideration to unmarked cities.

W S T backtrack to S backtrack to W Y

Q X R P

Y

W S T

Z

Page 50: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

50

Search for a Path: BacktrackingHow do we implement an exhaustive search with backtracking?

Consider two approaches:

1) Use a stack to hold the path under consideration from the desired origin, O, to the most recently visited city.

After step (5) of our “Basic Idea” the stack would contain

O C1 C2 . . . Cm Cm+1

2) Alternatively, implement a recursive solution, where the nested recursive calls to a search function store the path implicitly.

Let’s focus first on the stack-based solution.

Page 51: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

51

Search for a Path: Example

W

QX

R P

Y

S T

ZContents of stack in a search

for a path from P to Z (top is at left) P R P X R P R P P W P S W P T S W P S W P W P Y W P Z Y W P

Page 52: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

52

Search for a Path: Stack-Based Solutionbool findPath( int origCity, int destCity )

{ pathStack.push( origCity ); visited[ origCity ] = true;

while( !pathStack.isEmpty( ) )

{ pathStack.getTop( curCity );

if( curCity = = destCity ) return true;

if( /* no flights exist from curCity to any unvisited city */ )

pathStack.pop( );

else

{ /* set nextCity to any unvisited neighbor of curCity */

pathStack.push( nextCity ); visited[ nextCity ] = true; }

}

return false;

}

Page 53: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

53

Search for a Path: Storing the FlightsHow do we store the flights made by the airline?

Use an Adjacency List: an array of linked lists, where each element of the array corresponds to a city from which a flight could originate. The value of each array element is a pointer to a linked list of destinations that are accessible by a direct flight from the originating city.

TSRQP ZYXW

T W S RR X X

ZYW

NULL NULL

NULLNULL

NULL

NULL

NULL

NULL

NULL

Array:

L Li in sk te sd

Page 54: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

54

Search for a Path: Recursive Solution

bool findPath( int origCity, int destCity )

{

visited[ origCity ] = true;

if( origCity = = destCity ) return true;

while( /* there is an unvisited neighbor of origCity */ )

{

/* set nextCity to any unvisited neighbor of curCity */

if( findpath( nextCity, destCity ) ) return true;

}

return false;

}

Page 55: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

55

Search for a Path: Observations

• A recursive solution is sometimes conceptually simpler and can be expressed more concisely than a non-recursive, stack-based solution.

• Any recursive solution can be implemented non-recursively using a stack. In fact, this is how recursion is implemented by the compiler.

Page 56: 1 Stacks (Walls & Mirrors - Chapter 6). 2 Overview The ADT Stack Array Implementation of a Stack Linked-List Implementation of a Stack Application Domain:

56

Search for a Shortest Path• Our strategy of using backtracking to perform an

exhaustive search is guaranteed to find a path from a given origin to a given destination if one exists.

• This strategy is not guaranteed to find the shortest path if the search is stopped when the first successful path is found.

• If the search is allowed to continue until all paths from a given origin have been considered, then one can pick the shortest path, if desired.

• When, due to an extremely large number of candidate paths, an exhaustive search is not possible, heuristics are sometimes used to make a “good guess” at the shortest path without searching through all the possibilities.