Download presentation
Presentation is loading. Please wait.
Published byPeter Hill Modified over 9 years ago
1
Stacks
2
2 What Are Stacks ? PUSHPOP 0 MAX Underflow Overflow
3
Stacks3 The Stack ADT The Stack ADT stores arbitrary objects Insertions and deletions follow the last-in first-out scheme Think of a spring-loaded plate dispenser Main stack operations: push(object o): inserts element o pop(): removes and returns the last inserted element Auxiliary stack operations: getTop(): returns a reference to the last inserted element without removing it size(): returns the number of elements stored isEmpty(): returns a Boolean value indicating whether no elements are stored
4
Stacks4 Applications of Stacks Direct applications Page-visited history in a Web browser Undo sequence in a text editor Saving local variables when one function calls another, and this one calls another, and so on. Indirect applications Auxiliary data structure for algorithms Component of other data structures
5
Stacks5 Array-based Stack A simple way of implementing the Stack ADT uses an array We add elements from left to right A variable keeps track of the index of the top element S 012 t … Algorithm size() return t + 1 Algorithm pop() if isEmpty() then error (Empty Stack) else t t 1 return S[t + 1]
6
Stacks6 Array-based Stack (cont.) The array storing the stack elements may become full A push operation will then throw a Full Stack Error condition Limitation of the array- based implementation Not intrinsic to the Stack ADT S 012 t … Algorithm push(o) if (t = S.length 1) then error (Full Stack) else t t + 1 S[t] o
7
Stacks7 Example: What does this code slice do? int main( ) { int n; double item; double numbers[n]; printf( " Type in an integer n followed by n decimal numbers.\n"); printf(" The numbers will be printed in reverse order.\n”); scanf(“%d”, &n); for (int i = 0; i < n; i++) { scanf(“%d, &item); push(item); } printf( “\n\n”); while (!empty( )) { printf( “%d ”, getTop( )); item = pop( ); } return 0; }
8
Stacks8 Stack: Example const int MaxStack = 10; const char EmptyFlag = '\0'; int top; int items[MaxStack]; enum { FullStack = MaxStack, EmptyStack = -1 }; // better enum Err_code {FullStack...} top = EmtyStack; bool push(int); int pop(); int getTop() bool empty(); bool full(); bool push(int x){ if (full()) return false; items[++top] = x; return true; } int pop(){ if (empty()) return EmptyFlag; return items[top--]; } int getTop(){ if (empty()) return EmptyStack; return items[top]; }
9
Stacks9 Stack: Example bool full() { if (top + 1 == FullStack) { printf( "Stack Full at %d \n“, MaxStack); return true; } return false; } bool empty(){ if (top == EmptyStack) { printf("Stack empty \n“); return true; } return false; } int main(void){ /* Define stack */ int s1 [ MaxStack ]; /* fill in here the necessary statements that use stack functions */ }
10
Stacks10 Exp: Prime Divisors of a Number Read an integer and print all its prime divisors in descending order. Note that the smallest divisor greater than 1 of any integer is guaranteed to be a prime 2100/2 = 1050 + 0 2100/2 = 1050 + 0 1050/2 = 525 + 0 1050/2 = 525 + 0 525/3 = 175 + 0 525/3 = 175 + 0 175/5 = 35 + 0 175/5 = 35 + 0 35/5 = 7 + 0 35/5 = 7 + 0 7/7= 1 + 0 7/7= 1 + 0 7*5*5*3*2*2 = 2100 7*5*5*3*2*2 = 2100
11
Stacks11 Reverse Polish Calculator ? Read an operand push it onto the stack +,-,*,/ Arithmetic operations = Print the top of the stack Examples: ?a?b+= Read and store a and b, calculate and store their sum, and then print the sum (a+b)= ?a?b +?c?d+*= do (a+b)*(c+d) and print ?a?b?c - = * ?d + = do (a*(b-c))+d and print: 1. Push a, b, c onto the stacks, 2. Replace the pair b,c by b-c and print its value, 3. Calculate a*(b-c), 4. Push d onto the stack. 5. Finally, calculate and print (a*(b - z)) + d.
12
Stacks12 Get command of calculator char get command( ) { char command; bool waiting = true; printf( "Select command and press :“); while (waiting) { scanf(“%c”, &command); command = tolower(command); if (command == ‘?’ || command == ‘=’ || command == ‘+’ || command == ‘−’|| command == ‘*’ || command == ‘/’ || command == ‘q’) waiting = false; else { printf( "Please enter a valid command: \n" ); printf(“[?]push to stack [=]print top \n"); printf(“[+] [−] [*] [/] are arithmetic operations \n"); printf(“[Q]uit. \n"); } return command; }
13
Stacks13 Adding and printing ?p?q+= bool do_command(char command) { double p, q; switch (command) { case ‘?’: printf(“Enter a number: "); flush(); scanf(“%d, &p); if (push(p) == false) printf(“Warning: Stack full, lost number \n"); break; case ‘=’: if ( (p = getTop()) == EmptyFlag) printf(“Stack empty \n”); else printf(“%d \n”, p); break; case ‘+’: if ((p = getTop()) == EmptyFlag) printf(“Stack empty \n”); else { p = pop( ); if ((q = getTop()) == EmptyFlag { printf(“Stack has just one entry\n”); push(p); } else { q = pop( ); if (push(q + p) == false) printf(“Warning: Stack full, lost result\n”); } } break; /* Add options for further user commands. */ case ‘q’: printf(“Calculation Finished.\n"; return false; } return true; }
14
Stacks14 Exp: Bracket checking int main( ) /* Post: Notice the use of any bracket mismatch in the standard input */ char symbol, match; bool is_matched = true; while (is_matched && (symbol = getchar( )) != “\n”) { if (symbol == ‘{‘ || symbol == ‘(‘ || symbol == ‘[‘) push(symbol); if (symbol == ‘}’ || symbol == ‘)’ || symbol == ‘]’) { if (empty( )) { printf("Unmatched closing bracket %c detected \n“); is_matched = false; } else { match = getTop(); match = pop( ); is_matched = (symbol == ‘}’ && match == ‘{‘) || (symbol == ‘)’ && match == ‘(‘) || (symbol == ‘]’ && match == ‘[‘); if (!is_matched) printf("Bad match %c %c \n“, match, symbol”); } if (! empty( )) printf("Unmatched opening bracket(s) detected.\n“); }
15
Stacks15 Performance and Limitations Performance Let n be the number of elements in the stack The space used is O(n) Each operation runs in time O(1) Limitations The maximum size of the stack must be defined a priori, and cannot be changed Trying to push a new element into a full stack causes an implementation-specific exception
16
Stacks16 Computing Spans Given an an array X, the span S[i] of X[i] is the maximum number of consecutive elements X[j] immediately preceding X[i] such that X[j] X[i] Spans have applications to financial analysis E.g., stock at 52-week high 63452 11231 X S
17
Stacks17 Quadratic Algorithm Algorithm spans1(X, n) Input array X of n integers Output array S of spans of X # S new array of n integers n for i 0 to n 1 don s 1n while s i X[i s] X[i] 1 2 … (n 1) s s 11 2 … (n 1) S[i] s n return S 1 Algorithm spans1 runs in O(n 2 ) time
18
Stacks18 Computing Spans with a Stack Keep in a stack the indices of the elements visible when “looking back” Scan the array from left to right Let i be the current index Pop indices from the stack until finding index j such that X[i] X[j] Set S[i] i j Push x onto the stack
19
Stacks19 Linear Algorithm Algorithm spans2(X, n) # S new array of n integers n A new empty stack 1 for i 0 to n 1 don while ( A.isEmpty() X[top()] X[i] ) don j A.pop()n if A.isEmpty() then n S[i] i 1n else S[i] i jn A.push(i)n return S 1 Each index of the array Is pushed into the stack exactly once Is popped from the stack at most once The statements in the while-loop are executed at most n times Algorithm spans2 runs in O(n) time
20
Stacks20 Growable Array-based Stack In a push operation, when the array is full, instead of throwing an exception, we can replace the array with a larger one How large should the new array be? incremental strategy: increase the size by a constant c doubling strategy: double the size Algorithm push(o) if t = S.length 1 then A new array of size … for i 0 to t do A[i] S[i] S A t t + 1 S[t] o
21
Stacks21 Comparison of the Strategies We compare the incremental strategy and the doubling strategy by analyzing the total time T(n) needed to perform a series of n push operations We assume that we start with an empty stack represented by an array of size 1 We call amortized time of a push operation the average time taken by a push over the series of operations, i.e., T(n)/n
22
Stacks22 Incremental Strategy Analysis We replace the array k = n / c times The total time T(n) of a series of n push operations is proportional to n + c + 2c + 3c + 4c + … + kc = n + c(1 + 2 + 3 + … + k) = n + ck(k + 1)/2 Since c is a constant, T(n) is O(n + k 2 ), i.e., O(n 2 ) The amortized time of a push operation is O(n)
23
Stacks23 Doubling Strategy Analysis We replace the array k = log 2 n times The total time T(n) of a series of n push operations is proportional to n + 1 + 2 + 4 + 8 + …+ 2 k = n 2 k + 1 1 = 2n 1 T(n) is O(n) The amortized time of a push operation is O(1) geometric series 1 2 1 4 8
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.