Transcript Stacks

Stacks
• Example: Stack of plates in cafeteria.
• Stack => a list data structure in which elements are
inserted in and removed from the same end, the top of
the stack.
• Use of Stacks => Computer system software such as
compilers and operating system.
• A stack is called a last in, first out (LIFO) list. The last
element stored is the first to be removed.
• Operations on a stack
- push a new object on
Push
the top of the stack
- pop the top object
from the stack
C
B
A
B
A
Pop
Stacks
• Because of the push operation which adds elements to a
stack, a stack is sometimes called a pushdown list.
• If a stack contains a single item and the stack is popped,
the resulting stack contains no items and is called the
empty stack.
• Push operation is applicable to any stack.
• Pop operation cannot be applied to the empty stack
because such a stack has no element to pop. Therefore,
before applying the pop operation to a stack, we must
ensure that the stack is not empty.
• The result of an illegal attempt to pop or access an item
from an empty stack is called underflow.
Implementing a stack using arrays
• An integer variable stack_top tells us which is the top
element.
Push 7
5 12
5
12
7
Pop returns 7
stack_top
stack_top
Problem: Cannot hold more than 4 elements
Implementing a Stack using Link Lists
• A pointer topp points to the top of the stack.
Stack of three characters
topp
C
+
2
Stack after insertion (push) of ‘/’
/
C
+
2
List Representation of a Stack
typedef char stack_element_t;
typedef struct stack_node_s
{
stack_element_t element;
struct stack_node_s *restp;
} stack_node_t;
typedef struct
{
stack_node_t *topp;
} stack_t;
Push Function
void push(stack_t *sp, // pointer to the stack
stack_element_t c) // element to add
{
stack_node_t *newp; // pointer to new stack
// creates and defines new node
newp = (stack_node_t *) malloc(sizeof(stack_node_t));
newp->element = c;
newp->restp = sp->topp;
sp->topp = newp; //sets stack pointer to point to new node
}
Implementation of the pop Operation
• The possibility of underflow must be considered in
implementing the pop operation.
• The user may attempt to pop an element from an empty
stack. Such an attempt is illegal and should be avoided.
• The function Pop should perform the following actions:
- If the stack is empty, print a warning message and
halt execution.
- Remove the top element from the stack.
- Return this element to the calling program.
If we don’t check for empty stack and call pop with an
empty stack, the value topp would be -1 and an attempt
would be made to access the nonexistent element stack[-1].
Pop Function
stack_element_t pop(stack_t *sp)
{
stack_node_t *to_freep; // pointer to node removed
stack_element_t ans;
// value at top of stack
to_freep = sp->topp;
// saves pointer to node
// being deleted
ans = to_freep->element;
// retrieves value to return
sp->topp = to_freep->restp; // deletes top node
free(to_freep);
// deallocates space
return (ans);
}
Stack Manipulation with Functions push & pop
#include <stdio.h>
#include <stdlib.h>
void push(stack_t *sp, stack_element_t c);
stack_element_t pop(stack_t *sp);
int main(void)
{
stack_t s = {NULL};
// stack is initially empty
push(&s, ‘2’);
// builds the stack
push(&s, ‘+’);
push(&s, ‘C’);
push(&s, ‘/’);
printf(“\nEmptying stack:\n”);
// empties stack element
while (s.topp != NULL)
printf (“%c\n”, pop(&s));
return (0);
}
Problem solving using Stacks
• Mathematical expression that includes several sets of
nested parentheses:
7 - ((X * ((X + Y) / (J -3)) + Y) / (4 - 2.5))
• We want to ensure that the parentheses are nested
correctly so that
- 1. There are an equal number of right and left
parentheses.
- 2. Every right parenthesis is preceded by a
matching left parenthesis.
Check
1. ((A + B)
violates condition 1
2. A + B(
violates condition 1
3. )A + B(-C
violates condition 2
4. (A + B)) - (C + D violates condition 2
Problem solving using Stacks
• We can solve this problem by using parenthesis count.
• Parenthesis count => the number of left parentheses
minus the number of right parentheses that have been
encountered from the left end up to a particular point.
• The expression will be valid if
- The parenthesis count at the end of the expression is
0. This means that the number of left parentheses is
the same as the number of right parentheses.
- The parenthesis count at each point in the expression
is nonnegative. This means that no right parenthesis
is encountered for which a matching left parenthesis
not previously been encountered.
Parenthesis Count at various points of Expressions
Expressions:
• ( ( A + B )
1 2 2 2 21
Parenthesis count at the end
1
Validity
invalid
• A + B (
0 0 0 1
1
invalid
• ) A + B ( - (
-1 -1 -1 -1 0 0 1
1
invalid
• ( ( A + B ) )
1 2 2 2 21 0
0 at the end and
nonnegative at each point
valid
Extension of this problem
• In the earlier problem, expressions contain only
parentheses as scope delimiter.
• However, an expression can contain three different types
of scope delimiters: parentheses(), brackets [], and braces
{}.
Examples:
(A + B]){
or
{(A - B) - (C - [D + E])}
• Therefore, we need to count not only how many scopes
are opened but also their types.
• Using stacks we can easily solve this problem.
• Left parenthesis => opening a scope
• Right parenthesis => closing a scope
Solution of this problem using Stack
• Whenever a scope opener is encountered, it is pushed
onto the stack.
• Whenever a scope ender is encountered, the stack is
examined.
• If the stack is empty, the scope ender does not have a
matching opener and the string is invalid.
• If the stack is nonempty, we pop the stack and check
whether the popped item corresponds to the scope ender.
• If a match occurs, we continue.
• If does not, the string is invalid.
• When the end of the string is reached, the stack must be
empty. Otherwise one or more scopes have been opened
which have not been closed, and the string is invalid.
Parenthesis stack at Various stages of Processing
• Expression:
{
(
{
{….
{( ….
{(A - B) - (C - [D + E])}
(
{
{
{(A - B) ...
(
{
{(A -B) - (C - [D+E]...
{(A - B) - ( ..
[
(
{
{(A - B) -(C- [ ..
{
{(A-B) - (C - [D+E]).. {(A- B) - (C -[D+E])}
Why we have used Stacks ?
• The last scope (parenthesis) to be opened must be first
to be closed. This is simulated by a stack in which the
last element arriving is the first to leave.
• Each item on the stack represents a scope that has been
opened but that has not been closed.
• Pushing an item onto the stack corresponds to opening a
scope and popping an item from the stack corresponds
to closing a scope, leaving one less scope open.
• Notice that at any point, we examine only the element at
the top of the stack.
• In general, a stack is used in any situations that calls for
a last-in, first-out discipline or that displays a nesting
pattern.
Infix, Postfix, and Prefix
• The sum of A and B can be represented in three different
ways.
Infix notation: In infix notation, the operator is
between the two operands. Humans generally use
this notation. E.g. A + B
Prefix notation: In prefix notation, the operator
precedes the two operands. Computers prefer this
notation. E.g + A B
Postfix notation: In postfix notation, the operator
follows the two operands. E.g A B +
Use of postfix Notation
• To evaluate a complex infix expression, a compiler
would first convert the expression to postfix notation.
• Then evaluate the postfix version of the expression.
• Each of these algorithms requires only a single left-toright pass of the expression.
• Each algorithm uses a stack in support of its operation.
• In each the stack is used for a different purpose.
Rules of Conversions of different notations
• The rules to convert an infix to postfix:
- The operation with highest precedence are
converted first.
- After a portion of the expression has been
converted to postfix it is to be treated as a single
operand.
• The order of precedence (highest to lowest)
- Exponentiation
- Multiplication/ Division
- Addition/ Subtraction
• When unparenthesized operators of the same precedence
are scanned, the order is from left to right except in the
case of exponentiation, where the order from right to left.
Example
• Expression: A + B * C (standard infix notation)
• It requires knowledge of which of the two operations, +
or *, is to be performed first.
• We know that multiplication has higher precedence over
addition. So, A + B * C is interpreted as A + ( B * C ).
• Suppose we want to rewrite A + B * C in postfix.
The steps are:
• A+(B*C)
parentheses for emphasis
• A+(BC*)
convert the multiplication
• A( BC*)+
convert the addition
• ABC*+
postfix form
Another Example
• Expression: (A + B) * C (infix notation)
• In this example, addition will be converted before
multiplication because parentheses have higher
precedence than multiplication.
• Suppose we want to rewrite ( A + B ) * C in postfix.
The steps are:
• (A+ B)*C
infix form
• (A B + ) * C
convert the addition
• (A B + ) C *
convert the multiplication
• AB+C*
postfix form
More Examples
Rewrite the infix ( A + B ) * ( C - D ) in postfix.
The steps are:
• (A+B)*( C- D)
• ( A B + ) * ( C D -)
• ( A B + C D -) *
• AB+CD -*
infix form
convert the parenthesized
operations
convert the multiplication.
postfix form
More Examples
Rewrite the infix A$B*C-D+E/F/(G+H) in postfix.
The steps are:
•
•
•
•
•
•
•
•
A$B*C-D+E/F/(G+H)
infix form
A$B*C-D+E/F/(GH+)
convert the parenthesized operation
(AB$)*C-D+E/F/(GH+)
convert the exponentiation.
(AB$C*)-D+E/F/(GH+)
convert the multiplication.
(AB$C*)-D+(EF/)/(GH+) convert the division (left most).
(AB$C*)-D+(EF/GH+/)
convert the division
(AB$C*D-)+(EF/GH+/)
convert the subtraction.
(AB$C*D-EF/GH+/)+
convert the addition.
• AB$C*D-EF/GH+/+
postfix form
Conversion from Infix to Prefix
• The precedence rules for converting an expression from
infix to prefix and from infix to postfix are identical.
• The only difference is that the operator is placed before
the operands rather than after them.
• Example: Rewrite the infix A + B - C in prefix.
The steps are:
• A+ B -C
infix form
• (+ A B ) - C
convert the addition
• - (+A B C )
convert the subtraction
• - +AB C
prefix form
Another Example
Rewrite the infix ( A + B ) * ( C - D ) in prefix.
The steps are:
• (A+B)*( C- D)
• ( +A B ) * ( - C D )
• *(+AB -CD)
• *+AB- CD
infix form
convert the parenthesized
operations
convert the multiplication.
prefix form
• Note that the prefix form of a complex expression is not
the mirror image of the postfix form.
Advantage of using Postfix and prefix
• Postfix and prefix forms of expressions allow us an
unambiguous form of the original expressions without
the use of cumbersome parentheses.
• Consider two expressions:
• A + ( B * C ) and (A + B) * C (infix forms)
• The parentheses in the first expression are superfluous.
• However, the parentheses in the second expression are
necessary to avoid confusion with the first.
• The corresponding postfix expressions are:
ABC*+
No parentheses
AB+C*
• The order of operators in the postfix expressions
determines the actual order of operations in evaluating it.
Algorithm to Evaluate a Postfix Expression
The algorithm is as follows:
1 Append the NULL character (‘\0’) to the end of the postfix
expression. When the NULL character is encountered, no further
processing is necessary.
2 While ‘\0’ has not been encountered, read the expression from left
to right.
If the current character is a digit,
push its integer value on the stack
Otherwise, if the current character is an operator,
pop the two elements of the stack into variables x and y.
Calculate y operator x.
Push the result of the calculation on the stack.
3 When the NULL character is encountered in the expression, pop
the top value of the stack. This is the result of the postfix
expression.
Example
• Postfix Expression: 6 2 3 + - 3 8 2 / + * 2 $ 3 +
• Steps for evaluation are as follows:
623+-382/+*2$3+
65-382/+*2$3+
1382/+*2$3+
134+*2$3+
17*2$3+
72$3+
49 3 +
52
Example: 6 2 3 + - 3 8 2 / + * 2 $ 3 +
Symb
6
2
3
+
3
8
2
/
+
*
2
$
3
+
opnd1
2
6
6
6
6
8
3
1
1
7
7
49
opnd2
3
5
5
5
5
2
4
7
7
2
2
3
value
5
1
1
1
1
4
7
7
7
49
49
52
opndstk
6
6, 2
6, 2, 3
6, 5
1
1, 3
1, 3, 8
1, 3, 8, 2
1, 3, 4
1, 7
7
7, 2
49
49, 3
52
Another example
• Postfix Expression: 6 2 + 5 * 8 4 / • Steps for evaluation are as follows:
62+5*84/85*84/40 8 4 / 40 2 38
Algorithm for Creating a Postfix Expression
1 Push a left parentheses ‘(‘ on the stack.
2 Append a right parenthesis’)’ to the end of infix.
3 While the stack is not empty, read infix from left to right and do the following:
If the current character in infix is a digit, copy it to the next element of postfix.
If the current character in infix is a left parenthesis, push it on the stack.
If the current character in infix is an operator,
Pop operators (if there are any) at the top of the stack while they have equal
or higher precedence than the current operator, and insert the popped
operators in postfix.
Push the current character in infix on the stack.
If the current character in infix is a right parenthesis
Pop operators from the top of the stack and insert them in postfix until a left
parenthesis is at the top of the stack.
Pop (and discard) the left parenthesis from the stack
Explanation
• Expression: A + B * C (standard infix notation)
symb
A
+
B
*
C
postfix string
A
A
AB
AB
ABC
ABC *
ABC * +
opstk
+
+
+*
+*
+
Infix to Prefix
1) A + B = +AB
2) A + B - C = (+AB) - C = - + ABC
3) A + B * C = A + (*BC) = + A * BC
4) A * (B + C) = A * (+ BC) = * A+ BC
5) A * B + C = (* AB) + C = + * ABC
6) (A + B) * (C - D) = (+ AB) * (- CD) = * + AB - CD
Infix to Prefix
7) (( A + B ) * C - ( D - E )) $ (F + G)
= ((+ AB) * C - (- DE)) $ (+ FG)
= ((* + ABC) - (- DE)) $ (+ FG)
= (- * + ABC - DE) $ (+ FG)
= $ - * + ABC - DE + FG
10) (A + B) * (C + D - E) * F
= (+ AB) * (( + CD) - E) * F
= (+ AB) * (- + CDE) * F
= (* + AB - + CDE) * F
= * * + AB - + CDEF
8) A - B / ( C * D $ E)
= A - B / (C * ($ DE))
= A - B / (* C $ DE)
= A - (/ B * C $ DE)
= - A / B * C $ DE
11) 7) A $ B * C - D + E / F / (G + H)
= A $ B * C - D + E / F / (+GH)
= ($AB) * C - D + E / F / (+GH)
= (*$ABC) - D + E / F / (+GH)
= (*$ABC) - D + (/EF) / (+GH)
= (*$ABC) - D + (//EF + GH)
= (- * $ ABCD) + (//EF + GH)
= + - * $ ABCD//EF + GH
9) A + B * C + D - E * F
= A + ( * BC) + D - (* EF)
= (+ A * BC) + D - (* EF)
= (+ + A * BCD) - (* EF)
= - + + A * BCD * EF
Infix to Postfix
1) A + B = AB +
2) A + B - C = (AB +) - C = AB + C 3) A + B * C = A + ( BC *) = ABC * +
4) A * (B + C) = A * (BC +) = ABC + *
5) A * B + C = (AB *) + C = AB * C +
6) (A + B) * (C - D) = (AB +) * (CD-) = AB + CD - *
Infix to Postfix
7)
=
=
=
=
=
=
=
A $ B * C - D + E / F / (G + H)
A $ B * C - D + E / F / (GH +)
(AB $) * C - D + E / F / (GH +)
(AB $ C *) - D + E / F / (GH +)
(AB $ C *) - D + (EF /) / (GH +)
(AB $ C *) - D + (EF / GH + /)
(AB $ C * D -) + (EF / GH + /)
AB $ C * D - EF / GH + / +
8) ((A + B) * C - (D - E)) $ (F + G)
= ((AB +) * C - (DE -)) $ (FG +)
= ((AB + C *) - (DE -)) $ (FG +)
= (AB + C * DE - - ) $ (FG + )
= AB + C * DE - - FG + $
9)
=
=
=
=
A - B / (C * D $ E)
A - B / (C * (DE $))
A - B / (CDE $ *)
A - (BCDE $ * /)
ABCDE $ * / -
10) (A + B) * (C + D - E) * F
= (AB +) * ((CD +) - E) * F
= (AB +) * (CD + E -) * F
= (AB + CD + E - *) * F
= AB + CD + E - * F *
11) A + B * C + D - E * F
= A + (BC *) + D - (EF *)
= (ABC * +) + D - (EF *)
= (ABC * + D + ) - (EF*)
= ABC * + D + EF * -
Prefix to Infix
1) + AB = A + B
2) - + ABC = - (A + B)C = A + B - C
3) + A * BC = +A(B * C) = A + (B * C)
4) * A + BC = * A(B + C) = A * (B + C)
5) + * ABC = + (A * B) C = (A * B) + C
6) * + AB - CD = * (A + B)(C - D) = (A + B) * (C - D)
Prefix to Infix
7)
=
=
=
=
=
+ - * $ ABCD / / EF + GH
+ - * (A $ B) CD / / EF + GH
+ - ((A $ B) * C)D / / EF + GH
+ (((A $ B) * C) - D) / (E / F) + GH
+ (A $ B * C - D)((E / F) / (G + H))
A $ B * C - D + E / F / (G + H)
8) $ - * + ABC - DE + FG
= $ - * (A + B)C - DE + FG
= $ - ((A + B) * C) - DE + FG
= $ - ((A + B) * C)(D -E) + FG
= $ - ((A + B) * C)(D -E) (F + G)
= $ ((A + B) * C - (D - E)) (F + G)
= ((A + B) * C - (D - E)) $ (F + G)
9) - + + A + BCD * EF
= - ++ A + BCD (E * F)
= - + + A (B + C) D ( E * F)
= - + ( A + (B + C)) D (E * F)
= - (A + B + C + D)(E * F)
= (A + B + C + D) - E * F
10) * * + AB - + CDEF
= * * (A + B) - (C + D) EF
= * * (A + B)(C + D - E) F
= * (A + B) * (C + D - E) F
= (A + B) * (C + D - E) * F
Postfix to Infix
1) AB + = A + B
2) ABC * + = A (B * C) + = A + ( B * C)
3) ABC + * = A (B + C) * = A * (B + C)
4) AB * C + = ( A * B) C + = (A * B) + C
Postfix to Infix
5) ABC * + D + EF * = A (B * C) + D + (E * F) = (A + B * C)D + (E * F) = (A + B * C + D)(E * F) = (A + B * C + D) - (E * F)
6) AB + CD + E - * F *
= (A + B) CD + E - * F *
= (A + B)(C + D)E - * F *
= (A + B)(C + D - E) * F *
= (A + B) * (C + D - E) F *
= (A + B) * (C + D - E) * F
7) ABC + - D * EF + $
= A(B + C) - D * (E + F) $
= ( A - (B + C)) D * (E + F) $
= ((A - (B + C)) * D) (E + F) $
= ((A - (B +C)) * D) $ (E +F)