550 likes | 697 Views
CS 235102 Data Structures ( 資料結構 ). Chapter 3: Stacks and Queues Spring 2012. Stack – Abstract Data Type (ADT). Object: Stack An order list in which insertions and deletions are made at only one end. Operations: Insert(a) or Push(a) ::= insert element a into the stack .
E N D
CS 235102 Data Structures (資料結構) Chapter 3: Stacks and Queues Spring 2012
Stack – Abstract Data Type (ADT) • Object: Stack • An order list in which insertions and deletions are made at only one end. • Operations: • Insert(a) or Push(a) ::=insert element a into the stack. • Delete() or Pop() ::=delete and return top element from the stack. • IsFull::=return FALSE or TRUE. • IsEmpty::=return FALSE or TRUE.
Operatons on Stack • Stack operates in Last-In-First-Out (LIFO) order Insert A Insert B Insert C A B A C B A top top top empty
Operations on a Stack Delete Insert D B A D B A C B A top top top
Representation of a stack • Using a 1-D array • Stack [MAX_STACK_SIZE] • top: point to the top of the element of the stack • top = -1 denotes an empty stack.
Operations: Push Push( int *top, element item){ if (*top >= MAX_STACK_SIZE-1) {stackFull(); return; } *top = *top +1; stack[*top] = item; }
Operations: Pop /* return the top element from the stack */element Pop (int*top) { if (*top == -1)return StackEmpty(); item = stack[*top]; *top = *top-1; return item; }
Application of Stack • System stack: • used in the run time to process nested procedure calls • The return addresses of previous outer procedures are stored in the stack.
Application of Stack By the time Sub3 is called, the stack contains all three return addresses: Return address to Sub2 Return address to Sub1 Return address to main System stack
Application of Stack • Creation and activation: record for the invoked subprogram • return address for calling procedure • Parameters of current procedure • local variables in current procedure • When exit a subprogram, delete the activation record on the top of the stack.
Queue – Abstract Data Type (ADT) • Object: Queue • an ordered list in which all insertions take place at the end and all deletions take place at the other end • Operations: • Add(a) ::=insert element a at the rear of the queue. • DeleteQ() ::=delete and return front element from the queue. • IsFullQ::=return FALSE or TRUE. • IsEmptyQ::=return FALSE or TRUE.
Operations on a Queue Insert A A Insert B A B Insert C A B C Delete B C fr f r fr f r f r • Eg. First-In-First-Out (FIFO) order: • f: front pointer • r: rear pointer
Representation of a Queue Queue • Use a 1-D array • Queue [MAX_QUEUE_SIZE] • front, rear: two variables point to the two ends of the queue. • Initialization: front = -1; rear = -1 front: one less than the position of the first element in the queue.
Representation of a Queue Queue front rear • front == rear empty Queue
Operations: AddQ AddQ(int*rear, element item) { if (*rear == MAX_Queue_SIZE - 1){QueueFull(); return; } *rear = *rear +1;queue[*rear] = item;}
Operations: DeleteQ element DeleteQ(int*front, int rear) { if (*front == rear) return QueueEmpty(); *front = *front +1; return queue[*front];}
Operations: Problem Problem: a Job queue by operating system Q[1] Q[2] Q[3]…J_1 Insert J_1J_1 J_2 J_3 Insert J_2, J_3 J_2 J_3 Delete J_2 J_3 J_4 J_5 Insert J_4, J_5 J_3 J_4 J_5 Delete J_4 J_5 Delete The queue shifts to the right When queue is full, we need to move the entire queue left time consuming
Solution rear [5] [4] if rear == Max_Queue_Size -1 then rear = 0;else rear = rear +1; [3] [0] [1] rear = (rear+1) % Max_Queue_Size; [2] front Use a circular array to represent a queue,
How to test “Empty” & “Full” ? [0] [1] [3] [2] front rear Empty <=> front == rear
How to test “Empty” & “Full” ? [0] [1] [4] [2] [3] rear front Full <=> rear + 1 == front use only n-1 element use n elements will not be able to distinguish full or empty
AddQ using Circular Array AddQ( int front, int *rear, element item) { *rear = (*rear +1) % MAX_QUEUE_SIZE; if (front == *rear){QueueFull(); return; } Queue[*rear] = item; }
DeleteQ using Circular Array element DeleteQ(int*front, int rear) { if (*front == rear) return QueueEmpty(); *front = (*front +1) % MAX_QUEUE_SIZE; return queue[*front]; }
Evaluation of An Expression x = A/B-CHow to evaluate an expression ? let A=6, B=3, C=2(A/B)-C =(6/3)-2 =2-2 =0 (A/(B-C)) =(6/(3-2) ) =6/1 =6
Rules to evaluate an expression Assign precedence to operator, and Evaluate first the operator with higher precedence Left to right for the operator with the same precedence (in general), Right to left for prefix unary operators
Example 1 +, -, *, / ALUtwo operands & one result Compiler generates codes for the ALUEg: D=A+B*Cmul B C T1 add A T1 D source destination
Example 2 Eg2: D=A+B-C add A B T1 sub T1 C D Generates correct code so that when the code is evaluated, the expression is computed correctly.
Infix and Postfix Notations • Infix notation = operator comes in–between the operandsEg: A+B*C A+B-C • It is not easier for compiler to generate code to evaluate an expression in infix notation • Postfix notation: each operator appears after its operands Eg: A+B-C infixAB+C- postfix
Translate infix to postfix • How to translate from infix to postfix? • A/B-C • First Algorithm: (1) Fully parenthesize the expression (2) Move all operators so that they replace their corresponding right parenthesis (3) Delete all parenthesis
Examples Eg1: ( ( A / B ) – C ) A B / C - Eg2: ( ( A + B ) - ( C * D ) ) A B + C D * - Eg3: ((((A / B ) – C ) + ( D * E ) ) - ( A * C ) ) A B / C - D E * + A C * -
Example 1 + T1 - T2 • What is good about postfix? • Evaluation of postfix expressiondone in one passEg1: A + B - CA B + C - add A B T1 sub T1 C T2 • Scan the expression from left to right • Use stack to hold operands
Example 1: A B + C - A B T1=A+B A B A C T2=T1-C C T1=A+B ‘-’ pop operands C, T1 T2 = T1 – C push T2 to stack ‘+’ pop operands A, B T1 = A + B push T1 to stack
Example 2 A B A T1=A+B A B ‘+’ pop two operands A, B T1 = A+B push the result C T1=A+B D C T1=A+B C D T2=C*D T1=A+B “*” pop two operands C, D T2 = C*D push the result Ex2:A+B-C*D A B + C D * -
Example 2 T2=C*D T1=A+B T3=T1-T2 ‘-’ pop T1, T2 T3 = T1 – T2 push the result Ex2:A+B-C*D A B + C D * -
Example 3 • Ex3. A B / C – D E * + A C * - T1=A/B A B A A B ‘/’ pop two operands T1 = A/B push result
Example 3 • Ex3. A B / C – D E * + A C * - C T2=T1-C C T1=A/B ‘-’ pop two operands T2=T1-C push the result
Example 3 • Ex3. A B / C – D E * + A C * - T3=D*E T2=T1-C D T2=T1-C E D T2=T1-C E D “*” pop two operands T3= D*E push the result
Example 3 • Ex3. A B / C – D E * + A C * - T4=T3+T2 A T4=T3+T2 C A T4 C A “*” Pop two operands T4=T3+T2 Push the result
Example 3 • Ex3. A B / C – D E * + A C * - T5=A*C T4 T6=T4-T5 “-” Pop two operands T6=T4– T5 Push the result “*” Pop two operands T5=A*C Push the result
Postfix vsInfix • Postfix- when you see an operator, operands have been seen in front of it (on the top of the stick) • Infix- when you see an operator, you do not know if the operand is ready • Thus when we see the operator, we cannot do the evaluation for this operator yet.
Evaluate Postfix Expression EvalPostfixExpression(expression e) {x = NextToken(e); while (x is not end of expression) do { if (x is an operand) then push(&top, x) else{ /* x is an operator */ 1. pop the correct number of operands for x from stack; 2. perform the operation;(or generatethe code) 3.push the result onto the stack; }x = NextToken(e); } }
How to Transform Infix to Postfix? • How to translate from infix to postfix? • First algorithm: • “Fully parenthesize” the expression • Convert full parenthesized expr. to postfix • Disadvantage: • Need two passes of scanning the expression
Algorithm Two Alg2: 1. scan the expression just once 2. utilize stack Observations: 1: The positions of operands are not changed passing any operands to the output immediately 2: Store the operator in stack until it is time to pass it to the output
Algorithm Two • “it is time”: • means that the precedence of operator in the stack is larger or equal to that of the incoming operator (left-to-right associativity)
Example 1 eoe - / / - - A A B AB/ AB/C AB/C- 2.1 push operator to the stack 2.2 operators are taken out of stack as long as their precedence is higher or equal to the precedence of new incoming operatorEg1: A / B – C A B / C -
Example 2 * - * - + + - AB+C A A B AB+ eoe * - - AB+CD AB+CD* AB+CD*- Eg2: A + B – C * D A B + C D * -
Example 3 - / / - / A B AB/ A A B + * - + + AB/C- AB/C-D AB/C Eg3: A / B – C + D * E – A * C
Example 3 - * + - + A B/C-DE AB/C-DE*+ * - * - AB/C-DE*+A AB/C-DE*+AC AB/C-DE*+AC*- Eg3: A / B – C + D * E – A * C
Transform Infix Expr. with ( ) ( + * ( * ( * + ( * AB A Expression with ( ) 1. ‘( )’ evaluate first 2. ‘(‘push ‘(’to stack always 3. when ’(’ is on top of the stack, then push other operators (always) to stack4. ‘)’ pop the operators until you see the matched ‘(‘ Eg. A * ( B + C ) / D
Transform Infix Expr. with ( ) Eg. A * ( B + C ) / D ) / eoe / + ( * * ABC+*D ABC+*D/ ABC ABC+