890 likes | 1.09k Views
Stacks. Briana B. Morrison Adapted from Alan Eugenio. Topics. Define Stack APIs Applications Create Hex Number Recursion Converting from Infix to Postfix Evaluating Postfix Converting from Infix to Prefix Implementation Array based Linked list based. Stacks.
E N D
Stacks Briana B. Morrison Adapted from Alan Eugenio
Topics • Define Stack • APIs • Applications • Create Hex Number • Recursion • Converting from Infix to Postfix • Evaluating Postfix • Converting from Infix to Prefix • Implementation • Array based • Linked list based Stacks
Stacks • A stack is a sequence of items that are accessible at only one end of the sequence. Stacks
Pushing/Popping a Stack • Because a pop removes the item last added to the stack, we say that a stack has LIFO (last-in/first-out) ordering. Stacks
CLASS stack CLASS stack <stack> <stack> Constructor Operations stack(); Create an empty stack bool empty(); const Check whether the stack is empty. Return true if it is empty and false otherwise. Stacks
CLASS stack <stack> Operations void pop(); Remove the item from the top of the stack. Precondition: The stack is not empty. Postcondition: Either the stack is empty or the stack has a new topmost item from a previous push. void push(const T& item); Insert the argument item at the top of the stack. Postcondition: The stack has a new item at the top. Stacks
CLASS stack <stack> Operations int size() const; Return the number of items on the stack. T& top() const; Return a reference to the value of the item at the top of the stack. Precondition: The stack is not empty. const T& top() const; Constant version of top(). Stacks
DETERMINE THE OUTPUT FROM THE FOLLOWING: stack<int> my_stack; for (int i = 0; i < 10; i++) my_stack.push (i * i); while (!my_stack.empty()) { cout << my_stack.top() << endl; my_stack.pop(); } // while Stacks
Implementing stack an adapter of vector • The standard library implements the stack as an adapter of any sequential container. • The member functions are delegated to the member functions of the container. • Any of the three sequential containers can be used: vector, list, or deque. • The standard library uses the deque by default. • We will use the vector, and describe the deque in the next chapter. Stacks
Implementing Stack as Extension of Vector Top element of the Stack is at the highest index Stacks
stack Code template<typename Item_Type> void stack<Item_Type>::push(const Item_Type& item) { container.push_back(item); } template<typename Item_Type> Item_Type& stack<Item_Type>::top() { return container.back(); } template<typename Item_Type> const Item_Type& stack<Item_Type>::top() const { return container.back(); } Stacks
Stack Code (2) template<typename Item_Type> void stack<Item_Type>::pop() { container.pop_back(); } template<typename Item_Type> bool stack<Item_Type>::empty() const { return container.empty(); } template<typename Item_Type> size_t stack<Item_Type>::size() const { return container.size(); } Stacks
STACK APPLICATIONS Stacks
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 Stacks
STACK APPLICATION HOW COMPILERS IMPLEMENT RECURSION Stacks
EACH ACTIVATION RECORD CONTAINS: 1. A VARIABLE THAT CONTAINS THE RETURN ADDRESS IN THE CALLING METHOD; 2. FOR EACH VALUE FORMAL PARAMETER, A VARIABLE THAT CONTAINS A COPY OF THE ARGUMENT; 3. FOR EACH REFERENCE FORMAL PARAMETER, A VARIABLE THAT CONTAINS THE ADDRESS OF THE ARGUMENT; 4. FOR EACH VARIABLE DEFINED IN THE METHOD’S BLOCK, A VARIABLE THAT CONTAINS A COPY OF THAT DEFINED VARIABLE. Stacks
THERE IS A RUN-TIME STACK TO HANDLE THESE ACTIVATION RECORDS. PUSH: WHEN FUNCTION IS CALLED POP: WHEN EXECUTION OF FUNCTION IS COMPLETED Stacks
AN ACTIVATION RECORD IS SIMILAR TO AN EXECUTION FRAME, EXCEPT THAT AN ACTIVATION RECORD HAS VARIABLES ONLY, NO CODE. YOU CAN REPLACE RECURSION WITH ITERATION BY CREATING YOUR OWN STACK. Stacks
C++ Run-time Stack main() { int i = 5; foo(i); } foo(int j) { int k; k = j+1; bar(k); } bar(int m) { … } • The C++ run-time system keeps track of the chain of active functions with a stack • When a function is called, the run-time system pushes on the stack a frame containing • Local variables and return value • Program counter, keeping track of the statement being executed • When a function returns, its frame is popped from the stack and control is passed to the method on top of the stack bar PC = 1 m = 6 foo PC = 3 j = 5 k = 6 main PC = 2 i = 5 Stacks
STACK APPLICATION CONVERTING FROM INFIX TO POSTFIX Stacks
IN INFIX NOTATION, AN OPERATOR IS PLACED BETWEEN ITS OPERANDS. a + b c – d + (e * f – g * h) / i Stacks
OLD COMPILERS: INFIX MACHINE LANGUAGE THIS GETS MESSY BECAUSE OF PARENTHESES. NEWER COMPILERS: INFIX POSTFIX MACHINE LANG. Stacks
In POSTFIX Notation, An OPERATOR is placed IMMEDIATELY AFTER its OPERANDS. INFIX POSTFIX a + b ab+ a + b * c abc*+ a * b + c ab*c+ (a + b) * c ab+c* Stacks
PARENTHESES ARE NOT NEEDED, AND NOT USED, IN POSTFIX. Stacks
LET’S CONVERT AN INFIX STRING TO A POSTFIX STRING. x – y * z Stacks
POSTFIX PRESERVES THE ORDER OF OPERANDS, SO AN OPERAND CAN BE APPENDED TO POSTFIX AS SOON AS THAT OPERAND IS ENCOUNTERED IN INFIX. Stacks
INFIX POSTFIX x – y * z x Stacks
INFIX POSTFIX x – y * z x THE OPERANDS FOR ‘-’ ARE NOT YET IN POSTFIX, SO ‘-’ MUST BE TEMPORARILY SAVED SOMEWHERE. (STACK) Stacks
INFIX POSTFIX x – y * z xy Stacks
INFIX POSTFIX x – y * z xy THE OPERANDS FOR ‘*’ ARE NOT YET IN POSTFIX, SO ‘*’ MUST BE TEMPORARILY SAVED SOMEWHERE, AND RESTORED BEFORE ‘-’. Stacks
INFIX POSTFIX x – y * z xyz Stacks
INFIX POSTFIX x – y * z xyz* – Stacks
Suppose, instead, we started with x*y-z After moving ‘x’ to postfix, ‘*’ is temporarily saved, and then ‘y’ is appended to postfix. What happens when ‘-’ is accessed? INFIX POSTFIX x * y – z xy Stacks
THE TEMPORARY STORAGE FACILITY IS A STACK. HERE IS THE STRATEGY FOR MAINTAINING THE STACK: Stacks
Converting Infix to Postfix • Analysis: • Operands are in same order in infix and postfix • Operators occur later in postfix • Strategy: • Send operands straight to output • Send higher precedence operators first • If same precedence, send in left to right order • Hold pending operators on a stack Stacks
INFIX GREATER, PUSH Stacks