610 likes | 757 Views
6.The Stack Data structure deals with the study of how data is organized in memory and how efficiently data can be retrieved and manipulated. Data structures allows programmers to write efficient programs. data is efficiently retrieved ,manipulated and organized in memory.
E N D
6.The Stack • Data structure deals with the study of how data is organized in memory and how efficiently data can be retrieved and manipulated. • Data structures allows programmers to write efficient programs. data is efficiently retrieved ,manipulated and organized in memory. • Data structures(D.S) can be classified as 1.primitive D.S 2.non primitive D.S
Primitive D.S • D.S that are manipulated directly by machine instructions. Ex: integers, floating point, characters and pointers. Non primitive D.S • D.S that cannot be manipulated directly by machine instructions. ex: arrays, structures, stacks, queues, linked lists, files. • They are further classified as 1.linear D.S D.S that show logical relationship between elements like stacks, queues, linked lists.
2.non linear D.S: ex: trees, graphs, files • Pointers are used extensively in implementing data structures. The Stack: • Special type of D.S where items are inserted at one end called the top of stack and deleted from the same end. • Last item inserted will be on the top of stack. • Last item inserted will be the first one to be deleted. Hence it is called Last In First Out(LIFO) or First In Last Out(FILO). Various operations on stacks • Insert an item into the stack.(Push) • Delete an item from the stack.(pop) • Display the contents of the stack.
top=-1 top D C top C top B B B top A A A A An example with pictorial representation of stack • Consider a stack S which is initially empty. • Let the maximum size of stack be 8. • top points to the top of stack. Since stack is empty, it is set to -1 initially. • Now lets insert A,B,C,D to stack. As an item is inserted, top is incremented. After A After B After C After D
L top top C K B B B top A A A After 1st pop After 2nd pop After inserting K and L Now, lets perform 2 pop operations • Pop removes the top item from stack and returns it. • After the item is removed, top is decremented.
Primitive stack operations • push( ): Increments top and adds item to the stack at top. push(S,A)– S is the stack and A is the item to be inserted. Displays message “stack full” when stack is full.i.e In the previous stack, if we try to insert 9th element. • pop( ): Removes the top item from stack and returns it. inti=pop(S); Displays message “stack empty” if we try to pop when there is no element in stack.i.e when top==-1 3. empty( ): Returns true if stack is empty, false otherwise. boolean empty(S); 4. display( ): display contents of stack. These functions are user defined.
Applications of stack 1.Conversion of expressions when we write mathematical expressions in a program, we use infix expressions. This will be converted into equivalent m/c instructions using stacks. 2. Evaluation of expressions Arithmetic expressions in the form of either prefix or postfix can be easily evaluated using stacks. 3.Recursion stacks are used extensively in recursion. 4.Other applications Find whether a string is palindrome or not To check whether a given expression is valid or not.
When fun2() is being called all the information pertained to fun1() (flow, flags, return address, etc.,) will be pushed into the stack. Similarly, when fun3() is being called information pertained to the function fun2() will be pushed into the stack. So, when fun3() returns the information set related to fun2() will be popped out first, then information pertained to fun1() (when fun2() returns). Another example is in the case of keeping the history while browsing the internet. When hyperlink is clicked, information related to current page is pushed onto stack and control goes to the clicked page. While returning back to previous page, stack is popped and information of the previous page is obtained
Representing stacks in c To implement a stack, we need to have • An array to hold the elements of stack. • An integer variable to indicate the top of stack. Using these we need to write functions for push, pop and display. Stacks can be implemented in c by either • Without using structures. • Using structures.(most preferred) • No matter in what way the stack is implemented, it should have a n array and integer variable.
Implementing stack without structure #include<stdio.h> #define STACK_SIZE 5 //max size of stack Void main() { int top; //top of stack; int s[10]; //hold stack elements int item; //item to be inserted intdel_item; //popped item int choice; //user choice top=-1; //stack empty initially for(; ;) //loop until exit { printf(“enter your choice”); printf(“1.push 2.pop 3.display 4.exit”); scanf(“%d”,&choice); }
switch(choice) { case 1: printf(“enter item to be pushed”); scanf(“%d”, &item); push(item,&top,s); //call push function break; case 2:del_item=pop(&top, s); printf(“deleted item is %d”,del_item); break; case 3:display(top,s); break; default: exit(0); } //end of switch } //end of for } //end of main
/*push function*/ Void push(int item, int *top, int s[]) { if(*top==STACK_SIZE-1) { printf(“stack full”); exit(0); } (*top)++; //increment top s[*top]=item; //insert the item }
/*pop*/ int pop(int *top, int s[]) { int del_item; if(*top==-1) { printf(“stack empty”); return(0); } else { del_item=s[*top]; //remove top element (*top)--; //decrement top return(del_item); } }
Void display(int top, int s[]) { int i; if(top==-1) { printf(“stack empty”); exit(0); } printf(“contents is”); for(i=0;i<=t;i++) //start from bottom to top printf(“%d”, s[i]); } • In push and pop address of top is passed because top is local to main and we want to update top when item is pushed or popped. • In display, we aren't changing the top. But its value is used to traverse the stack from bottom to top.hence address need not be passed.
Implementing stack using structure #include<stdio.h> #define STACK_SIZE 5 //max size of stack struct stack { int top; int sarray[STACK_SIZE]; }; typedef struct stack STACK; Void main() { int item, choice; //item to be inserted and user choice STACK s; //stack variable s.top=-1; //stack empty initially for(; ;) //loop until exit { printf(“enter your choice”); printf(“1.push 2.pop 3.display 4.exit”); scanf(“%d”,&choice);
switch(choice) { case 1: printf(“enter item to be pushed”); scanf(“%d”, &item); push(item,&s); //call push function break; case 2:item=pop(&s); if(item= = -1) printf(“empty stack”); else printf(“deleted item is %d”,item); break; case 3:display(s); break; default: exit(0); } //end of switch } //end of for } //end of main
/*push function*/ Void push(int item, STACK *stck) { if(stcktop==STACK_SIZE-1) { printf(“stack full”); exit(0); } stcktop++; //increment top stcksarray[stcktop]=item; //insert the item }
/*pop*/ int pop(STACK stck) { int del_item; if(stcktop= =-1) return(-1); else { del_item=stcksarray[stcktop];//remove top element stcktop--; //decrement top return(del_item); } }
Void display(STACK stck) { int i; if(stck.top==-1) { printf(“stack empty”); exit(0); } printf(“contents is”); for(i=0;i<=stck.top;i++) //start from bottom to top printf(“%d”, stck.sarray[i]); } • In push and pop address of stack ‘s’ is passed because ‘s’ is local to main and we want to update top when item is pushed or popped. • In display, we aren't changing the top. But its value is used to traverse the stack from bottom to top. hence address need not be passed.
Display function can also be implemented by passing address of structure or stack array because there is no harm in passing address even if the value is not changed. Void display(STACK *stck) { int i; if(stcktop==-1) { printf(“stack empty”); exit(0); } printf(“contents is”); for(i=0;i<=stcktop;i++) //start from bottom to top printf(“%d”, stcksarray[i]); }
Checking whether given expression is valid or not using stack Checking an expression is nothing but checking 1.Whether there are equal number of right and left parenthesis. 2.Whether right parenthesis is preceded by a matching left parenthesis. If both the above conditions are satisfied, expression is valid. Ex: ((A+B) or A+B( are not valid expressions because they violate condition 1. )a+b(-c violate condition 2. (a+b)) violate both the conditions. (a+b) * (c+d) is a valid expression. Stacks can be used to check this.
Algorithm for checking expression • Scan the expression from left to right. • Whenever a scope opener( ‘(‘,’{‘,’[‘ ) is encountered while scanning the expression, it is pushed to stack. • Whenever as scope ender( ‘)’, ‘}’, ‘]’) is encountered, the stack is examined. If stack is empty, scope ender does not have a matching opener and hence string is invalid. If stack is non empty, we pop the stack and check whether the popped item corresponds to scope ender. If a match occurs, we continue. If it does not, the string is invalid. 4. When the end of string is reached, the stack must be empty; otherwise 1 or more scopes have been opened which have not been closed and string is invalid.
( ( ( ( (a+b) Pop ‘(‘ since there is ‘)’ & continue (a+b) *( Push ‘(‘ (a+b) *(c+d End of string reached but stack not empty. Hence invalid push ‘(‘ ( ( push ‘(‘ (a+b) pop‘(‘ and continue (a+b)*c+d) Stack empty when ‘)’ encountered.hence invalid Ex1:(a+b) * (c+d Ex2:(a+b)*c+d)
( ( ( push ‘(‘ (a+b) pop‘(‘ and continue (a+b)*( push‘(‘ and continue { { ( ( (a+b)*({c*d) No match between closing scope ‘)’ and opening scope ‘{‘. Hence invalid. (a+b)*({ push ‘{ and continue‘ Ex3: (a+b)*({c*d)
{ ( ( ( ( push ‘(‘ and continue (a+{ push‘{‘ and continue (a+{b*c} pop‘{‘ and continue ( ( ( (a+{b*c}+(c*d) Pop ‘(‘ (a+{b*c}+(c*d)) Pop ‘(‘. End of string and stack empty. Hence valid (a+{b*c}+( push ‘( and continue‘ Ex4: (a+{b*c}+(c*d))
Checking for palindrome • Algorithm • Scan the string from left to right till the end and push every char you encounter during the scan to the stack. • Rescan the string left to right till end and do the following for every char you encounter during scan. Pop one char and compare current char with the popped one.If no match report immediately non palindrome other wise proceed to the next char.
Infix, postfix, prefix expressions and stacks Infix expression: • Operators will be between two operands. ex: a+b*c, a+b*c+d, (a+b)*c, (a+b)*(c+d). Postfix expressions • Operator follows two operands. ab+, ab*, abc*+ Prefix expressions • Operators precedes two operands. • These expressions can be converted to other form. i.e infix to prefix, infix to postfix and so on
Converting infix to postfix • infix can be converted to postfix by placing the operator after two operands while scanning from left to right. a+bab+, a*bab* • When there are multiple operators and parentheses, precedence of operators comes into picture. Operations with highest precedence is considered first for conversion and converted part is considered as single unit(operand) and process is continued. • Operations within the parenthesis is considered first for conversion because parentheses have highest precedence. • For operators, order precedence is given below 1.exponentiation($ or ^) 2.multiplication/division 3.addition
Ex1: a+b*c Here * is having higher precedence than +. So * is considered first which gives bc*. Now bc* is considered as a single unit. i.e a + bc*. Here a and bc* are considered as separate units. Finally converting the intermediate expression gives abc*+ Ex2:(a+b)*c operation within parenthesis is considered first which gives ab+ . Now ab+ and c are 2 separate operands i.eab+ * c Converting this intermediate expression will give ab+c* Ex3: (a+b)*(c+d) After converting first parenthesis we get ab+ *(c+d). After converting 2nd parenthesis we get ab+ * cd+. After converting the the above expression we get ab+cd+*
When operators with same precedence are scanned, the order is assumed to be left to right, except in the case of exponentiation, where the order is right to left. Ex1: a+b+c Here both the operators are + and have same precedence. Hence considering from left to right we get ab+ + c. converting this intermediate expression will give us ab+c+ Ex2: a$b$c Here also $ have same precedence. In case of $, order is from right to left. Hence considering from right we get a $ bc$. Now convert this intermediate expression. Hence we get abc$$ Ex3:a*b/c * and / have same precedence. Order is from left to right. Hence we ab* / c. finally we get ab*c/
Converting infix with multiple operators to postfix Ex1: a$b*c-d+e/f/(g+h) 1.a$b * c - d + e / f / gh+ ab$*c – d + e / f / gh+ 2.ab$c* - d + e / f / gh+ 3.ab$c*d- + e / f / gh+ 4.ab$c*d- + ef/ / gh+ 5.ab$c*d- + ef/ / gh+ 6.ab$c*d- + ef/gh+/ 7.ab$c*d-ef/gh+/+
Ex2: ((a+(b-c)*d)$e+f) 1.( ( a + bc- * d ) $ e + f ) 2.( ( a + bc-d* ) $ e + f ) 3.( abc-d*+ $ e + f ) 4.abc-d*+e$ + f 5.abc-d*+e$f+
Converting infix to prefix • Infix can be converted to prefix by placing the operator before two operands. • Precedence rules is same as in the case infix to postfix. Ex:a+b+ab a+b*c+a*bc (a+b)*c*+ab a+b-c-+abc a*b/c/*abc a$b$c$a$bc (a+b)*(c+d)*+ab+cd
Converting infix with multiple operators to prefix Ex1:((a+(b-c)*d)$e+f) ( ( a + -bc * d ) $ e + f ) ( ( a + *-bcd ) $ e + f ) ( +a*-bcd $ e + f ) ( $+a*-bcde + f ) +$+a*-bcdef Ex2:a-b/(c*d$e) a - b / ( c * $de ) a - b / *c$de a - /b*c$de -a/b*c$de
Another method a$b*c-d+e/f/(g+h) • Put all implicit brackets.(According to precedence and associativity) • ((((a$b)*c)-d)+((e/f)/(g+h))) • Replace every ) with corresponding operator and remove ( • ab$c*d-ef/gh+/+ 5. Converting to prefix requires change of roles of ( and ) in step 3. 6. +-*$abcd//ef+gh
Evaluating postfix expression using stack Steps: 1.Scan the postfix expression from left to right 2.If an operand is encountered, push it on to the stack. 3.If an operator is encountered, pop the top two elements from the stack, perform the required operation based on operator and push the result back on stack. 4.Perform this operation until end of expression is reached. 5.At the end, stack contains the final result.
623+-382/+*2$3+ Symbolop1op2op1 operator op2stack 6 6 2 6,2 3 6,2,3 + 2 3 5 6,5 - 6 5 1 1 3 1,3 8 1,3,8 2 1,3,8,2 / 8 2 4 1,3,4 + 3 4 7 1,7 * 1 7 7 7 2 7,2 $ 7 2 49 49 3 49,3 + 49 3 52 52
23+4* Symbolop1op2op1 operator op2stack 2 2 3 2,3 + 2 3 5 5 4 5,4 * 5 4 20 20
/*program to evaluate postfix expression*/ #include<stdio.h> #include<math.h> #include<string.h> Struct stack { int top; int items[15]; }; typedef struct stack STACK; Void main() { int op1,op2,I,result; char postfix[15], symbol; STACK s; s.top=-1;
Printf(“enter postfix expression”); scanf(“%s”,postfix); for(i=0;i<strlen(postfix);i++) { symbol=postfix[i]; if(isdigit(symbol)) // call isdigit function push(symbol-’0’,&s); else { op2=pop(&s); op1=pop(&s); result=op(symbol,op1,op2); //call op function push(result,&s); } } result =pop(&s); Printf(“result is %d”,result); }
/*function op for performing operation on op1 and op2*/ int op(char symbol, int opnd1, int opnd2) { switch(symbol) { case ‘+’: return(opnd1+opnd2); break; case ‘-’: return(opnd1-opnd2); break; case ‘*’: return(opnd1*opnd2); break; case ‘/’: return(opnd1/opnd2); break; case’$’ case ‘^’: return(pow(opnd1,opnd2)); } }
Void push(int symb, STACK *stk) //push to stack { stktop++; stkitems[stktop]=symb; } Int pop(STACK *stk) //pop from stack { int item; item=stkitems[stktop--]; return item; } Int isdigit(char symb) //check symbol is digit or not { if(symb>=‘0’ && symb<=‘9’) return 1; else return 0; }
Converting infix to postfix Steps: 1.Scan the infix string from left to right. 2.If the symbol is operand, add it to postfix string. 3.Else 1. if current symbol is ‘(‘, push it to stack, whatever the top of stack may be. 2. if ‘(‘ is top of the stack and current symbol is any operator, push the symbol to stack. 3. if current symbol is ‘)’, pop the stack until the first ‘(‘ is encountered and add the popped elements to postfix string except ‘(‘.
4.if current symbol is an operator, compare the precedence of current symbol with the top of stack. If the precedence of current symbol is higher, push it to stack. Otherwise pop the stack until precedence of current symbol is greater than the top of stack and add all popped elements to postfix string and current symbol to stack. 5.Repeat this process until end of infix string is reached. 6.At the end, pop whatever is remained in stack to postfix string.
Ex1: a+(b*c) Steps current symbol postfix str stack 1 a a 2 + a + 3 ( a +( 4 b ab +( 5 * ab +(* 6 c abc +(* 7 ) abc* + End of string Now pop whatever is remained on top of stack and to postfix string. Hence final postfix string is abc*+
Ex2:((a-(b+c))*d)$(e+f) Steps current symbol postfix str stack 1. ( ( 2. ( (( 3. a a (( 4. - a ((- 5. ( a ((-( 6. b ab ((-( 7. + ab ((-(+ 8. c abc ((-(+ 9. ) abc+ ((- 10. ) abc+- ( 11. * abc+- (* 12. d abc+-d (*
Steps current symbol postfix str stack 13. ) abc+-d* 14. $ abc+-d* $ 15. ( abc+-d* $( 16. e abc+-d*e $( 17. + abc+-d*e $(+ 18. f abc+-d*ef $(+ 19. ) abc+-d*ef+ $ End of string Pop whatever is remained on stack and add to postfix string. abc+-d*ef+$
a*b+c*d+e*f Steps current symbol postfix str stack 1. a a 2. * a * 3. b ab * 4. + ab* + 5. c ab*c + 6. * ab*c +* 7. d ab*cd +* 8. + ab*cd*+ + 9. e ab*cd*+e + 10. * ab*cd*+e +* 11. f ab*cd*+ef +* End of string Pop * and + from stack and add to postfix string : ab*cd*+ef*+
Algorithm: Opstk=the empty stack While(not end of input) { symb=next input character. if(symb is an operand) add symb to postfix string. else { while(!empty(opstk) && prcd(stacktop(opstk),symb)) { topsymb=pop(opstk); add topsymb to postfix string; } if(empty(opstk)|| symb!=‘)’) push(symb,opstk); else //to discard open parenthesis topsymb=pop(opstk); } }
/* whatever is remained in stack is popped and added to string*/ While(!empty(opstk)) { topsymb=pop(opstk); add topsymb to postfix string; } /*precedence function*/ prcd(‘(‘,op)=FALSE, for any operator. prcd(op,‘(‘)=FALSE, for any operator other than ‘)’. prcd(op,’)’)=TRUE, for any operator other than ‘(‘.