The Stack

advertisement
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) /( 4 -2 .5 ) )
0012223444433444432221122222210
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 <<eltype>> 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==<elt>+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 lowlevel 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
+ab
Ab+
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
Infix
Prefix
Postfix
((a+b)*c-(de))$(f+g)
$-*+abc-de+fg
Ab+c*de—fg+$
Infix to Postfix Conversion
1
Opstk=the empty stack;
2
While(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 <stdio.h>
#include <stdlib.h>
#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*/
Download