990 likes | 1.25k Views
CSC 1052. Stacks . Outline. Stacks Basic operations Examples of use Queues Basic operations Examples of use Implementations Array-based and linked list-based. Static vs. Dynamic Structures. Recall that a static data structure has a fixed size Arrays are static ;
E N D
CSC 1052 Stacks
Outline • Stacks • Basic operations • Examples of use • Queues • Basic operations • Examples of use • Implementations • Array-based and linked list-based
Static vs. Dynamic Structures • Recall that a static data structure has a fixed size • Arrays are static; • once you define the number of elements it can hold, it doesn’t change.
Objects • A dynamic data structure grows and shrinks as required by the information it contains. • We have examined a data structure where two objects can be instantiated and chained together • The next reference of one Node object refers to the other node. • This will create a linked list of Node objects.
Stacks • A stack ADT is also linear, like a list or queue, • It maintains its information in a straight line. • Items are added and removed from only one end of a stack. • It is therefore LIFO: Last-In, First-Out.
Stacks • Stacks are often drawn vertically: PUSH POP add remove
Stacks • Some stack operations: - push -add an item to the top of the stack. - pop - remove an item from the top of the stack. - peek- retrieves top item without removing it. - empty- returns true if the stack is empty.
Stacks • A stack is a structure of ordered items such that items can be inserted and removed only at one end - called the top. • A stack is a LIFO or Last-in/First-Out structure. • Items are taken out of the stack in reverse order from their insertion.
Non-Computer Examples • Stack of papers • Stack of bills • Stack of plates • Expect O ( 1 ) time per stack operation. • (In other words, constant time per operation, no matter how many items are actually in the stack).
Stack • The stack specification lists a stack constructor and five methods. • One of the simplest stack implementations is to reverse a word. • Most compilers use stacks to analyze the syntax of a program.
Input NAT Push T Using a Stack to reverse a word Push N Push A T A N A N N Pop T Pop A POP N Output TAN A N N
STACKS applications • At all times in the execution of the reverse word program, • Only item can accessed from the stack, • This is the item on the TOP.
Peek() • We will use a method called peek() to view the top item • It looks at the top item but does not remove it. • Stacks are also used frequently to evaluate expressions
Applications – Evaluate expressions • Stacks can be used to check a program for balanced symbols (such as {}, (), []). • Example: {()} is legal, {(}) is not • (so simply counting symbols does not work).
Evaluate expressions • When a closing symbol is seen, • it must match themost recently seenunclosed opening symbol. • Therefore, a stack will be appropriate.
Balanced Symbol Algorithm • Make an empty stack. • Repeatedly read tokens(parenthesis); • if the token is: • an opening symbol, push it onto the stack • If it is a closing symbol • and the stack is empty,then report an error; • otherwise pop the stack and determine if the popped symbol is a match (if not report an error) • At the end of the file, if the stack is not empty, report an error.
Example • Input:{ ( ) } • Push { • Push ( stack now has { ( • Pop - Next comes a ), pop an item, it is ( which matches ). • Stack now has { • Pop – Next comes a}, pop an item, it is { which matches }. • End of file; stack is empty, so all is good. ( { {
Input: ( { } { } ) Read ) and Pop ( Read 2nd }, pop matching { Read and Push ( Read and Push { Read first } , pop matching { Read and Push 2nd { Empty Stack { ( { ( ( ( (
Input: [ { } { } ]{} Initial Empty Stack Read and Push [ Read and Push { Read first }, pop matching { { [ [ [ 1 2 3 4 Read and Push 2nd { Read 2nd }, pop matching { { And so on.. [ [ 5 6
Performance • Running time is O( N ), • where N is amount of data (that is, number of tokens). • Algorithm is online: • it processes the input sequentially, never needing to backtrack.
Balancing an expression • In the method IsBalanced(String exp) an expression is checked to see if all the parentheses match. • A charStack is set up whose legal characters are: “() {} [} “ • A switch is used
Method Stack • Matching symbols is similar to method call and method return, • because when a method returns, it returns to the most recently active method. • A method stack can be used to keep track of this.
Method call and return • Abstract idea: • when a method call is made, • save current state of the method on a stack. • On return, • restore the state by popping the stack.
Stack Frames or Activation Records • Programs compiled from modern high level languages make use of a • stack frame for the working memory of each method invocation. • When any method is called, a number of words - the stack frame-ispushed onto a program stack. • When the method returns, this frame of data is popped off the stack.
Stack frame or Activation Record • The Stack Frame or Record contains the : • Method arguments • Return address • And local variables of the method to be stored
method f( int x, int y) { int a; if ( end_cond ) return …; a = ….; return g( a ); }method g( int z ) { int p, q; p = …. ; q = …. ; return f(p,q); } Context for execution of f: Each frame contains : parameters, return address and local variables
Activation Records • As a method calls another method, • first its arguments, • then the return address and • finally space for local variables is pushed onto the stack.
current method environment. The top of stack stores the current method environment. • When the method is called, • the new environment(parameters etc.) is pushed onto stack. • When the method ends and returns, • the old environment is restored by popping the method environment.
Stack Frames • Ø Since each function runs in its own "environment" or context, • it becomes possible for a function to call itself - a technique known as recursion. • Ø This capability is extremely useful and extensively used • - because many problems are elegantly specified or solved in a recursive way.
Stack Frames • The most common applications for stacks have a space restraint • so that using an array implementation for a Stack is a natural and efficient one. • In most operating systems, allocation and de-allocation of memory costs time and space , e.g. • there is a penalty for the flexibility of linked list implementations..
Array Implementations • Stacks can be implemented with • an array and • aninteger top that stores the array index of the top of the stack. • Empty stack has top equal to -1.
Operations of a Stack • To push an object on the stack , • increment the top counter, and • write in the array position. • To popan item from the stack: decrement the top counter.
B top(1) top(-1) A top(0) A Stages
Array Doubling • If stack is full (because array size has been reached), we can extend the array, using array doubling. • We allocate a new, double-sized array and copy contents over: array =[T] new Object[ OldArray.length * 2 ]; for( int j = 0; j < OldArray.length; j++ ) Array[ j ] = OldArray[ j ]; OldArray = array;
Running Time • Without array doubling, • all operations are constant time, and • They do not depend on number of items in the stack. • With array doubling, • A push could occasionally be O( N ).
Big O of Stack • However, • if the array doubling occurs infrequently, • it is essentially O( 1 ) • because each array doubling that costs N assignments • is preceded by N/2 non-doubling pushes.
Infix Expressions • Example: 1 + 2 * ( 3 + 4 ) • Operands appear both before and after operator. • When there are several operators, • precedence and associativitydetermine how operators are processed.
Precedence and Associativity • Precedence:used to decide which of two operators should be processed. • Associativity:used to decide which of two operators should be processed when both operators have the same precedence. • Exponentiation: Right to Left • Multiplication/Division: Left to Right • Addition/Subtraction: Left to Right
Examples • 4-4-4 evaluates to -4 • 2^2^3 evaluates to 256 • Parenthesis override precedence and associativity.
Evaluating Infix expressions • In developing an application to use a stack to evaluate an infix expression, • several items must be considered.
A fully parenthized expressioncan be evaluated using the Stack data structure. • The implementation is complicated because of necessity for two stacks: • 1. Operator stack to store unprocessed operators. • 2. Operand stack to store unprocessed operands • The time analysis is: • 2n reads/peeks + n operations + 3n pushed + 3n popped = 9n
Difficulty of Infix Evaluation • Infix evaluation is difficult because of precedence rules: • when an operator is seen, it may or may not need to be deferred. • if it has a lower precedence than an operator further along in the expression. • Even if operator needs to be used, the second operand has still not been processed. • 1 + 2 * …
Postfix Expressions • An alternate form is the postfix expression • Let's examine a program that uses a stack to evaluate postfix expressions • In a postfix expression, the operator comes after its two operands
Infix to Postfix • We generally use infix notation, with parentheses to force precedence: (3 + 4) * 2 • In postfix notation, this would be written 3 4 + 2 * • In postfix, when you come to an operator, you already have it operands
Postfix Example – Let’s solve it • 1 2 3 * + • Push 1, Push 2, Push 3. • When * is seen, Pop 3, Pop 2, evaluate 2 * 3, and Push the result 6. • When + is seen, Pop 6, Pop 1, evaluate 1 + 6,and Push the result 7. • At end of expression, stack should have one item, • which is the answer.
To evaluate a postfix expression: • scan from left to right, determining if the next token is an operator or operand • if it is an operand, push it on the stack • if it is an operator, pop the stack twice to get the two operands, perform the operation, and • push the result onto the stack • At the end, only the answer will be on the stack
3 2 2 6 1 1 1 1 7 Push 1 Push 2 Push 3 Pop 3 Pop 6 Pop 2 Pop 1 Push 6 Push 7 Postfix Example, Continued WHEN YOU THE FIRST OPERATOR IS MET, -- THE *, POP THE 3 AND THE 2 , MULTIPLY THEM AND STORE THE PRODUCT - 6 – ON THE STACK The following operations will store the expression on the stack. As an operator is encountered the operators are popped and the appropriate operation performed. 1 2 3 * + When the last operator (+) is met, pop 6 and 1 and add them, and push the result on the stack
OLD COMPILERS translated infix expressions using two stacks into machine language. AN OPERATOR IS PLACED BETWEEN ITS OPERANDS c – d + (e * f – g * h) / i INFIX MACHINE LANGUAGE THIS GETS MESSY BECAUSE OF PARENTHESES AND NEED FOR TWO STACKS NEWER COMPILERS: INFIX POSTFIX MACHINE LANGUAGE