VIEWS: 65 PAGES: 46 CATEGORY: Education POSTED ON: 8/28/2010
CS212: Data Structures and Algorithms Lecture # 2 Stack Outline Introduction to Data Structures Stack Concepts Common examples Common operations Array implementation Applications of stack Reversing the string Balancing symbols Postfix expression evaluation Translating infix expression to postfix expression Array dynamic stack 2 Introduction to Data Structures A data structure is a way of storing data in a computer so that it can be used efficiently. Often a carefully chosen data structure will allow the most efficient algorithm to be used. A well-designed data structure allows a variety of critical operations to be performed, using as few resources, both execution time and memory space, as possible. 3 Stack A stack is a special case of a list. Rather than being allowed to insert a new item into the list at any place, additions to a stack are restricted to one end identified as the top of the stack. Deletions from the stack are also restricted to the top of the stack. Usually, only the item at the top of the stack is accessible to someone using the stack. A stack is often referred to as a FILO (First In Last Out) or LIFO (Last In First Out) list. The stack only allows addition and removal from the top so the order of removal is the opposite to that of insertion. 4 Stack Fundamental operations on a stack are Push - equivalent to an insert Pop - removes the most recently inserted element Example: Plates on a cafeteria serving line. This arrangement of trays is supported by a spring so that a person desiring a tray finds that only one is available at the surface of the tray counter. Top tray of pile Stacked trays Spring 5 Stack (Common Examples) Railway Shunting Suppose that we have four railway cars (DCBA) sitting on System the left-hand (input) track, as shown in the fig. We are required to rearrange these Input cars so that their order is (ACDB) that of the right-hand (output) D C B A A C D B track in the fig. We will restrict our shunting Before After system so that it typifies a stack. Stack Therefore, once a railway car has left the left-hand (input) track for the stack, it cannot return. Likewise, once a railway car has left the stack for the right hand (output) track, it cannot return to the stack. 6 Stack (Common Examples) Railway Shunting Clearly, at any given time, the only car that can move onto the System stack is the one at the front of the input stream. Input The only car that can move to the output stream is the one at the top D C B A A C D B of the stack. Before After Stack 7 Stack (Common Examples) Railway Shunting Operation Input Stack Output System Initial DCBA Push(A) DCB A Push(B) DC B Input A Pop() DC A B D C B A A C D B Push( C) D C B A Before After Push(D) D B C Stack A Pop() C DB A Pop() A CDB Pop() ACDB 8 Stack (Common Examples) A list of recently visited URLs for a web browser‟s “Back” and “Forward” buttons. The “undo” mechanisms in word processors. 9 Stack Assume an initially empty stack and following sequence of insertions and deletions: 10 Stack Implementation The five common operations which are associated with a stack are: Initialize: Initializes stack; that is, prepare it for use as a stack. Push: Inserts an element on top of stack and returns the new stack. Pop: Removes the top element from the stack and return the updated stack. IsEmpty: Returns “true” as the function result if stack contains no element, or otherwise returns “false”. TopValue: returns the top element of stack as the function result. 11 Stack Implementation (stack.h) #include<iostream.h> const int MAX = 10; template <class Type> class Stack { private: Type data[MAX]; // stack: array of any type int top; // number of top of stack public: Stack(); // constructor void push(Type); // put number on stack Type pop(); // take number off stack bool isEmpty();//checks if stack is empty or not Type topValue();//gives top value of stack }; 12 Stack Implementation (stack.h) template <class Type> Stack<Type>::Stack() { top = -1; } // Push a value onto the stack template <class Type> void Stack<Type>::push(Type item) { if (top == MAX-1) cerr << "Stack Full!\n"; else data[++top] = item; } 13 Stack Implementation (stack.h) // Pop a value off of the stack template <class Type> Type Stack<Type>::pop() { if (top == -1) { cerr << "Stack Empty!\n"; return 0; } else return data[top--]; } 14 Stack Implementation (stack.h) // Check whether the stack is empty template <class Type> bool Stack<Type>::isEmpty() { if (top == -1) return true; else return false; } // Provide the top value of the stack template <class Type> Type Stack<Type>::topValue() { return data[top]; } 15 Stack Implementation (driver.cpp) #include<iostream.h> #include"stack.h" void main() { // s1 is object of class Stack<float> Stack<float> s1; // push 2 floats, pop 2 floats s1.push(11.1); s1.push(22.2); s1.push(33.3); Output cout << "1: " << s1.pop() << endl; cout << "2: " << s1.pop() << endl; 1: 33.3 while (!s1.isEmpty()) { 2: 22.2 cout <<"from loop: " << s1.pop() <<endl; from loop: 11.1 } 16 Stack Implementation (driver.cpp) // s2 is object of class Stack<int> Stack<int> s2; // push 2 ints, pop 2 ints s2.push(123); s2.push(456); cout << "1: " << s2.pop() << endl; cout << "2: " << s2.pop() << endl; } // End of program Output 1: 456 2: 123 17 Applications of Stack Reversing the string Algorithm Steps 1. Push each character on to stack as it is read 1. When the line is finished, pop characters off the stack, and they will come off in the reverse order 18 Applications of Stack void reverseRead( ) { Stack<char> stack; //The Stack ‘stack’ is created char item; cin>>item; while (!stack.isFull()&&item!='$')//type $ from keyboard to stop input { stack.push(item); // push each character onto the stack cin>>item; } while(!stack.isEmpty() ) { item=stack.pop ();//Pop an element from stack cout<<item; } } 19 Applications of Stack Balancing Symbols Compilers use a program that checks whether every symbol (like braces, parenthesis, brackets, etc) in a program is balanced. The simple algorithm for this purpose is: 1. Make an empty stack. 2. Read the characters until end of file. 3. If the character is an open any thing, push it onto the stack. 4. If it is a close any thing, then 1. If the stack is empty report an error. 2. Otherwise Pop the Stack. 3. If the popped symbol is not the corresponding opening symbol, then report an error. 5. At the end of the file, if the stack is not empty report an error. 20 Polish Notation (Infix, Suffix, Prefix) a–b/c+d*e Precedence? 1. b/c 2. d*e 3. a – a1 /a1 = b/c / 4. t2 + a2 / t2 = a – b/c / /a2 = d*e/ 21 Polish Notation (Infix, Suffix, Prefix) Infix = a * b + c ((a*b) +c) Priority: 1. a * b 2. a1 + c / a1 = a * b / Prefix = * a b , +a1 c +*abc Suffix = ab* , a1c+ ab*c+ 22 Polish Notation (Infix, Suffix, Prefix) infix = a- b * c / d + e / f suffix =a – bc* / d + e / f a – bc*d/ + e / f a – bc*d/ + ef/ abc*d/- + ef/ abc*d/-ef/+ prefix =a - *bc / d + e / f a - /*bcd + e / f a - /*bcd + /ef -a/*bcd + /ef +-a/*bcd/ef 23 Polish Notation (Infix, Suffix, Prefix) Infix: a+b*c–d/f+e Suffix: abc*+df/-e+ Prefix: +-+a*bc/dfe 24 Applications of Stack Postfix Expression Evaluation 1. When a number is seen, it is pushed onto the stack 2. When an operator is seen, then pop two elements from stack and push the result onto the stack. Now we evaluate the following postfix expression. 6523+8*+3+* 3 2 1. The first four are placed on the stack. The resulting stack is 5 6 stack 25 Applications of Stack evaluating the following postfix expression. 3 6523+8*+3+* 2 5 6 stack 2. Next a + is read, so 3 and 2 are popped from the stack and 5 their sum 5 is pushed. 5 6 stack 26 Applications of Stack evaluating the following postfix expression. 6523+8*+3+* 5 5 6 stack 8 3. Next 8 is read and pushed. 5 5 6 stack 27 Applications of Stack evaluating the following postfix expression. 8 6523+8*+3+* 5 5 6 stack 4. Next a * is seen so 8 and 5 are popped as 8 * 5 = 40 is pushed 40 5 6 stack 28 Applications of Stack evaluating the following postfix expression. 6 5 2 3 + 8 * + 3 + * 40 5 6 stack 5. Next a + is read so 40 and 5 are popped and 40 + 5 = 45 is pushed. 45 6 stack 29 Applications of Stack evaluating the following postfix expression. 6523+8*+3+* 45 6 stack 6. Now 3 is pushed 3 45 6 stack 30 Applications of Stack evaluating the following postfix expression. 6523+8*+3+* 3 45 6 stack 7. Next symbol is + so pops 3 and 45 and pushes 45 + 3 = 48, so push 48 in stack. 48 6 stack 31 Applications of Stack evaluating the following postfix expression. 6 5 2 3 + 8 * + 3 + * 48 6 stack 7. Finally a * is seen and 48 and 6 are popped, the result 6 * 48 = 288 is pushed. 8. As there is no input, so pop the stack and we get the result. 288 stack 32 Applications of Stack Translating infix expressions to postfix expression 1. When an operand is read, it is immediately placed onto the output. 1. When an operator or left parenthesis comes then save it in the stack initially stack is empty. 1. If we see a right parenthesis, then we pop the stack, writing symbols until we encounter a (corresponding) left parenthesis, which is popped but not output. 1. If we see any other symbol („+‟, „*‟, „(„, etc) then we pop entries form the stack until we find an entry of lower priority. One exception is that we never remove a „(„ from the stack except when processing a „)‟. 1. When the popping is done, we push the operand onto the stack. 1. Finally, if we read the end of input, we pop the stack until it is empty, writing symbols onto the output. 33 Applications of Stack Translating infix expressions to postfix expression Convert the following infix expression to postfix expression. a+b*c+(d*e+f)*g 1. First the symbol a is read, so it is passed through to the output a 2. Then + is read and pushed onto the stack. output + stack 3. Next b is read and passed through to the output. ab output * 4. Next a * is read. The top entry on the operator stack has lower + precedence than *, so nothing is output and * is put on the . stack 34 Applications of Stack Converting the following infix expression to postfix expression. a+b*c+(d*e+f)*g 5. Next, c is read and output. abc output 6. The next symbol is a +. Checking the stack, we find that priority of stack top symbol * is higher than + . So we pop a * and place it on the output, Pop the other +, which is not of lower but equal priority, and then push +. * abc*+ + + output stack stack 35 Applications of Stack Converting the following infix expression to postfix expression. a+b*c+(d*e+f)*g 7. The next symbol read is an ‘(‘, which, being of highest precedence, is placed on the stack. ( + stack 8. Then d is read and output. abc*+d output 36 Applications of Stack Converting the following infix expression to postfix expression. a+b*c+(d*e+f)*g 9. We continue by reading a *. Since open parenthesis do not get removed except when a closed parenthesis is being processed, there is no output and we push * in stack * ( + stack 10. Next, e is read and output. abc*+de output 37 Applications of Stack Converting the following infix expression to postfix expression. a+b*c+(d*e+f)*g 11. The next symbol read is a +, since priority of stack top value is higher so we pop * and push +. + abc*+de* ( output + stack 12. Now we read f and output f. abc*+de*f output 38 Applications of Stack Converting the following infix expression to postfix expression. a+b*c+(d*e+f)*g 13. Now we read a ‘)’, so the stack is emptied back to the ‘(‘, we output a +. abc*+de*f+ + output stack 14. We read a * next; it is pushed onto the stack. * + stack 15. Now, g is read and output. abc*+de*f+g output 39 Applications of Stack Converting the following infix expression to postfix expression. a+b*c+(d*e+f)*g * + stack 16. The input is now empty, so pop output symbols from the stack until it is empty. abc*+de*f+g*+ output stack 40 Array Dynamic Stack //stack.h #include<iostream.h> template <class Element_Type> class Stack { private: /* This variable is used to indicate stack size*/ unsigned int size; /* This variable is used to indicate top of the stack */ int top; /* This pointer points to the array which behaves as stack, the space for this array is allocated dynamically */ Element_Type *data; public: Continue on next slide… 41 Array Dynamic Stack //This constructor creates a stack. Stack(unsigned int max_Size) { size = max_Size; top = -1; data = new Element_Type[max_Size]; } /* This Destructor frees the dynamically allocated space to the array */ ~Stack() { delete[] data; } Continue on next slide… 42 Array Dynamic Stack /*This function returns TRUE if the stack is full, FALSE otherwise.*/ bool isFull() { if (top == size-1) return true; else return false; } /*This function returns TRUE if the stack is empty, FALSE otherwise.*/ bool isEmpty() { if(top == -1) return true; else return false; } Continue on next slide… 43 Array Dynamic Stack // If stack is not full then push an element x in it void push(Element_Type x) { if(isFull()) cout<<"stack is full"; else data[++top] = x; } //if Stack is not empty then pop an element form it Element_Type pop() { if(isEmpty()) cout<<"stack is empty"; else return data[top--]; } Continue on next slide… 44 Array Dynamic Stack // This function makes the stack empty void makeEmpty() { top = -1; } /* This function returns the top element of stack */ Element_Type topValue() { if(isEmpty()) cout<<"stack is emepty"; else return data[top]; } }; //end of Stack class 45 Array Dynamic Stack //driver.cpp #include<iostream.h> #include"stack.h" void main() { int s; cout<<"Enter the stack size: "; cin>>s; Stack<char> stack(s); //size of this stack is decided at runtime stack.push('a'); stack.push('b'); Output stack.push('c'); Enter the stack size: 3 cout<<"1: "<<stack.pop()<<endl; 1: c cout<<"2: "<<stack.pop()<<endl; 2: b cout<<"3: "<<stack.pop()<<endl; } 3: a 46