stacks & recursion. stack pushpop lifo list - only top element is visible top
TRANSCRIPT
![Page 1: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/1.jpg)
Stacks & Recursion
![Page 2: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/2.jpg)
Stackpush pop
LIFO list - only top element is visible
top
![Page 3: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/3.jpg)
Defining the ADT "Stack"
• Data:– a linear collection of data items in which all
operations occur at one end, called the top• Basic Operations:– construct a stack (usually starts empty)– find out if stack is empty– push: add an item on top of the stack– accessing the topmost item• Top: retrieve the top item of the stack• Pop: remove the top item of the stack
![Page 4: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/4.jpg)
Some Implementation choices• fixed-size array– capacity (max # elements) decided at compile-time• could be too small for expected amount of data• could be too large, so space is wasted
– size (current # elements used)– fast
• dynamic array– capacity decided at run-time– size may be less than or equal to the capacity– uses pointers
• linked list– size changes as needed during program execution– uses pointers
![Page 5: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/5.jpg)
Implementation example
-1
myTop
myArray
76543210
typedef Complx StackElement;const int CAPACITY = 8;
int myTop;StackElement myStack[CAPACITY];
Complx X;push(&myStack,X);
initially empty (myTop is negative)
![Page 6: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/6.jpg)
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved. 0-13-140909-3
6
Using the stack - 1
• Model with an array– Let position 0 be top of stack
• Problem … consider pushing and popping– Requires much shifting
![Page 7: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/7.jpg)
7
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005
Pearson Education, Inc. All rights reserved. 0-13-140909-3
Using the stack - 2
• A better approach is to let position 0 be the bottom of the stack
• Thus our design will include– An array to hold the stack elements– An integer to indicate the top of the stack
![Page 8: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/8.jpg)
Addressing the problem
• Too much or too little space• Whatever size you pick, some day, there will
be too much data• In embedded systems, RAM is a premium• Need a dynamic solution (TBD)– Size changes as needed– No waste– Slower when adding new elements
![Page 9: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/9.jpg)
The "node" concept
• a "node" is one element of a stack• more than just the data– index of next and/or previous node– trivial for array implementations
• each node is a struct– data may be a struct INSIDE the node struct
struct node {int next;Complx data;};
node myStackNode[CAPACITY];
![Page 10: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/10.jpg)
Recursion
An alternative to loops
![Page 11: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/11.jpg)
What is recursion?
• a function calls itself– direct recursion
• a function calls its caller– indirect recursion
ff1
f2
![Page 12: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/12.jpg)
Recursion-1• Alternative to iteration (looping)– often more "elegant" and concise than a loop– sometimes very inefficient– easier to program than loops
• Useful when– a problem can be defined in terms of similar sub-problems– eventually reach a "known" answer (base case)
• Inefficient if duplicate values exist
![Page 13: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/13.jpg)
Head vs. Tail Recursion
• head recursion– requires "deepest" call to complete before any
values are known– current stack state must be preserved
• tail recursion– compiler can "collapse" the stack
![Page 14: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/14.jpg)
Head vs. Tail recursionNote: base case is ALWAYS 1st
tail(3) is: 3 2 1void tail(int n) {
if(n == 0) return;
else printf("tail - n=%i\
n",n);tail(n-1); //
}
head(3) is: 2 3void head(int n){
if(n == 1) return;
elsehead(n-1); //
printf("head - n=%i\n",n);); }
![Page 15: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/15.jpg)
Caveats
• Static data is NOT on the "stack"– never gets re-allocated– same values for EVERY call
• Must have an "exit" – prevent an infinite loop
![Page 16: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/16.jpg)
Outline of a Recursive Function
if (answer is known) provide the answer & exitelse call same function with a smaller version of the same problem
basecase
recursivecase
![Page 17: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/17.jpg)
Factorial (n) - looping
fact (int n){if (n<0) exit(1);
answer=1;for (i=1; i<=n; i++) answer=answer*i; // loop n
timesreturn (answer);
}• This is a simple problem
![Page 18: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/18.jpg)
Factorial (n) – head recursive
definition: Factorial (n) = n * Factorial (n-1)
int Fact (int n){if (n<0) exit(1); if (n == 0 | n==1) return 1; return n * Fact (n-1); // stack must be saved// cannot do the *'s until last value}
![Page 19: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/19.jpg)
Factorial "n" (tail recursive)
tail_fact (n, sofar) // set "sofar" same as "n"{ if (n == 0 | n==1)
return sofar; else // nothing to save on the stack
// because it is in the 2nd parameter
return tail_fact (--n, sofar * n); }
// here's how to run itprintf ("5!=%i",tail_fact(5,5));
![Page 20: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/20.jpg)
Keeping track
• compiler builds code to:– create a new stack pointer and stack space– put local variables & parameters on stack
• each "return" returns control to caller's next instruction (the inst after the call)
• returned value, is in caller's stack space– same as ANY function
• this is called "unwinding"
![Page 21: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/21.jpg)
Recursive Call Tree
int Fact (int n){ if (n == 0 | n==1) return 1; return n * Fact (n-1);}
Fact (4)
3*Fact (2)
4*Fact (3)
2*Fact (1)
24
24
6
2
![Page 22: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/22.jpg)
Fibonacci Series
Fibonacci sequence: 1, 1, 2, 3, 5, 8, 13, 21, ….n= 1 2 3 4
1 for n <= 2fib(n) =
fib(n-2) + fib(n-1) for n>2
for n=4: fib(2)+fib(3)1 + 2 3
![Page 23: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/23.jpg)
Tracing fib(6)
2 1
3 2
4 3
2 1
5
6
4
2 1
3 2
1 1
1
+
![Page 24: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/24.jpg)
Ackermann's function
A(0, n) = n + 1
A(m, 1) = A(m+1, 0)
A(m+1, n+1) = A(m, A(m+1, n))
![Page 25: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/25.jpg)
What Does a Compiler Do?
• Lexical analysis– divide a stream of characters into a stream of
tokens• total = cost + 0.08 * cost;• if ( ( cond1 && ! cond2 ) )
• Parsing– do the tokens form a valid program,– i.e. does it follow the syntax rules?
• Generate object code
![Page 26: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/26.jpg)
BNF (Backus-Naur form)(also called Backus Normal Form)
• a language used to define the syntax rules of a programming language
• consists of– productions – rules for forming some construct
of the language– meta-symbols – symbols of BNF that are NOT
part of the language being compiled– terminals – appear as shown– non-terminals – syntax defined by another
production
![Page 27: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/27.jpg)
BNF Syntax Rules • for a simplified boolean expression – bexpr -> bterm || bexpr | bterm– bterm -> bfactor && bterm | bfactor– bfactor -> !bfactor | (bexpr) | true | false | ident– ident -> alpha { alpha | digit|_}– alpha -> a .. z | A .. Z– digit -> 0 .. 9
• meta-symbols are in red• terminals are in blue• non-terminals are in black• special rules needed for "|" as part of a language
![Page 28: Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top](https://reader036.vdocuments.site/reader036/viewer/2022081519/56649e625503460f94b5dd28/html5/thumbnails/28.jpg)
bexpr -> bterm || bterm | bterm• What sequence of tokens is a valid bexpr?• if (there is a valid bterm)
if (nextToken is ||) if (there is a valid bterm) return true else return false else return trueelse return false
• Note: tokenizer must watch for the "||" without stopping at the first "|"