The Stack Alexander G. Chefranov CMPE-231 Spring 2012
Definition and Examples A stack is an ordered collection of items into which new items may be inserted and from which items may be deleted at one end, called the top of the stack. Unlike array, stack is a dynamic, constantly changing object Last-In-First-Out (LIFO) list
Primitive Operations When an item is added to a stack, it is pushed onto the stack, push(s,i) When an item is removed, it is popped from the stack, i=pop(s) Stack is also called a pushdown list If a stack contains a single item, and the stack is popped, the resulting stack contains no items and is called the empty stack Pop operation can’t be applied to the empty stack Empty(s) determines whether or not the stack is empty (returns TRUE if empty, FALSE otherwise) i=Stacktop(s) returns the top element of stack s without removing it (equivalent to i=pop(s); push(s,i);) Not defined for the empty stack The result of an illegal attempt to pop or access an item from an empty stack is called underflow
Example 7- ( ( x*( ( x+y) / ( j - 3) )+ y) /( ) ) Check that there are an equal number of right and left parenthesis, and every right parenthesis is preceded by a matching left parenthesis Each left parenthesis opens a scope, each right parenthesis closes a scope The nesting depth at a point is the number of scopes that have been opened but not yet closed at the point in an expression. Parenthesis count = number of left parenthesis – number of encountered right parenthesis 1.The parenthesis count at the end of the expression is 0 2.The parenthesis count at each point in the expression is nonnegative
Example (cont) {x+(y-[a+b])*c-[(d+e)]}/(h-(j-(k-[l-n]))) Valid=true; S=the empty stack; While(we have not read the entire string){ read the next symbol(symb) of the string; if(symb in {‘(‘,’[‘,’{‘}) push(s, symb); if(symb in {‘)’,’]’,’}’)) if(empty(s))valid=false; else{ i=pop(s); if(I is not the matching opener of symb) valid=false; }/*end else*/ }/*end while*/ If(!empty(s)) valid=false; if(valid) printf)”The string is valid”; Else printf(“the string is invalid”);
The Stack as an Abstract Data Type Abstract typedef > STACK(eltype); Abstract empty(s) STACK(eltype) s; Postcondition empty==(len(s)==0); Abstract eltype pop(s) STACK(eltype) s; Precondition empty(s)==FALSE; Postcondition pop==first(s’);s==sub(s’,1,len(s’)-1); Abstract push(s,elt) STACK(eltype) s; Eltype elt; Postcondition s== +s’;
Representing Stacks in C Array is static, stack is dynamic An array can be the home for a stack #define STACKSIZE 100 Struct stack{ int top; int items[STACKSIZE]; } Struct stack s;
Representing Stacks in C (cont 1) #define STACKSIZE 100 #define INT 1 #define FLOAT 2 #define STRING 3 Struct stackelement{ int type; union{ int ival; float fval; char *pval; } element Struct stack{ int top struct stackelement items[STACKSIZE]; }
Representing Stacks in C (cont 2) Struct stack s; Struct stackelement se; Se=s.items[s.top]; Switch(se.type){ Case INT: printf(“%d\n”, se.ival); Case FLOAT: printf(“%f\n”, se.fval); Case STRING: printf(“%s\n”, se.pval); } For simplicity, in the remainder, we assume that a stack is declared to have only homogeneous elements (so that unions are not necessary) The empty stack contains no elements (s.top==-1) Int empty(struct stack *ps){ if(ps->top==-1) return TRUE; else return FALSE; }
Representing Stacks in C (cont 3) Use of empty() is better than ps->top==1 as not implementation depending Modularization: individual functions are isolated into low- level modules whose properties are easily verifiable If precautions are taken at the time that a program is written that it is easily modifiable and comprehensible, the total time needed to get the program to run correctly is reduced sharply The mature professional is constantly concerned with the proper balance between code economy and code clarity
Representing Stacks in C (cont 4) Int pop(struct stack *ps){ if(empty(ps)){ printf(“Stack underflow\n”); exit(1); } return (ps->items[ps->top--]); }.. X=pop(&s);
Representing Stacks in C (cont 5) Void popandtest(struct stack *ps, int *px, int *pund){ if(empty(ps)){ *pund=TRUE; return; } *pund=FALSE; *px=ps->items[ps->top--]; return; } Popandtest(&s,&x,&und); If(und)/*take corrective actions*/ Else /*use value of x*/
Representing Stacks in C (cont 6) Void push(struct stack *ps, int x){ ps->items[++(ps->top)]=x; return; } Void push(struct stack *ps, int x){ if(ps->top==STACKSIZE-1){ printf(“Stack overflow\n”); exit(1); } ps->items[++(ps->top)]=x; return; }
Representing Stacks in C (cont 7) Pushand test(&s,x,&overflow); If(overflow)/*take remedial action*/ Else /*continue processing*/ Int stacktop(struct stack *ps){ if(empty(ps)){ printf(“Stack underflow\n”); exit(1); } else return (ps->items[ps->top]); }
Example: Infix, Postfix, and Prefix Notations + a b A b + Exponentiation a$b$c=a$(b$c) Multiplication/division Addition/subtraction a+b+c=(a+b)+c Prcd(‘*’,’+’)==TRUE, prcd(‘+’,’+’)==TRUE, Prcd(‘$’,’$’)==FALSE prcd(op1,op2) returns TRUE if op1 has precedence over op2 when op1 appears to the left of op2 in an infix expression without parenthesis, and FALSE otherwise InfixPrefixPostfix ((a+b)*c-(d- e))$(f+g) $-*+abc-de+fgAb+c*de—fg+$
Infix to Postfix Conversion 1Opstk=the empty stack; 2While(not end of input){ 3 symb=next input character; 4 if(symb is an operand) add symb to the postfix string; 5 else{ 6 while(!empty(opstk) && prcd(stacktop(opstk),symb)){ 7 topsymb=pop(opstk); 8 add topsymb to the postfix string; 9 } 10 push(opstk, symb); 11 }/*end else*/ 12 }/*end while*/ 13 while(!empty(opstk)){ 14 topsymb=pop(opstk); add topsymb to the postfix string; }/*end while*/
Infix to Postfix Conversion a*b+c*d A+b*c$d$e Prcd(‘(‘,op)=FALSE for any op Prcd(op,’(‘)=FALSE for any op other than ‘)’ Prcd(op,’)’)=TRUE for any op other than ‘(‘ Prcd(‘)’,op)=undefined for any op (error) 10 if(empty(opstk)||symb!=‘)’) push(opstk,symb); Else /*pop the open parenthesis and discard it*/ topsymb=pop(opstk); ((a-(b+c))*d)$(e+f)
Program to Convert from Infix to Postfix #include #define MAXCOLS 80 #define TRUE 1 #define FALSE 0 Struct stack{ int top; char items[MAXCOLS]; }; Void postfix(char *, char *); Void isoperand(char); Void popandtest(struct stack *,char *, int *); Int prcd(char, char); Void push(struct stack *, char); Char pop(struct stack *); Void main(){ char infix[MAXCOLS], postr[MAXCOLS]; int pos=0; While((infix[pos++]=getchar())!=‘\n’); Infix[--pos]=‘\0’; Printf(“The original infix expression is %s”, infix); postfix(infix,postr); printf(“%s\n”,postr); }/*end main*/
Program to Convert Infix to Postfix (cont 1) Postfix(char infix[],char postr[]){ int position, und, outpos=0; char topsymb, symb; struct stack opstk; opstk.top=-1; for (position=0;(symb=infix[position])!=‘\0’; position++) if(isoperand(symb))postr[outpos++]=symb; Else{ popandtest(&opstk,&topsymb,&und); while(!und && prcd(topsymb,symb)){ postr[outpos++]=topsymb; popandtest(&opstk,&topsymb,&und); } /*end while*/ If(und||(symb!=‘)’)) push(&opstk,symb); Else topsymb=pop(&opstk); }/*end else*/ While(!empty(&opstk))postr[outpos++]=pop(&opstk); postr[outpos]=‘\0’; }/*end postfix*/