Вы находитесь на странице: 1из 34

Stacks

Stack: restricted variant of list

elements may by inserted or deleted


from only one end : LIFO lists
top: the accessible end of the list
operations: push, pop
F
top
many applications
E
D
easy to implement:
C
B
A

arrays
linked lists

E.G.M. Petrakis

stacks, queues

Array Implementation
A simplified version of list
implementation

array of fixed size


top: always the first element
current is always the top element
push: insert at top !
pop: remove from top !

E.G.M. Petrakis

stacks, queues

Stack ADT
interface Stack {
public void clear( )
public void push(Object it)
public Object pop( )
public Object topValue( )
public bool isEmpty( )
}

E.G.M. Petrakis

//remove all ELEM's


//push ELEM onto stack
// pop ELEM from top
// value of top ELEM
// TRUE if stack is empty

stacks, queues

class AStack implements Stack { // Array based stack class


private static final int defaultSize = 10;
private int size;
// Maximum size of stack
private int top;
// Index for top Object
private Object [] listarray;
// Array holding stack
AStack() { setup(defaultSize); }
AStack(int sz) { setup(sz); }
private void setup(int sz) { size = sz; top = 0; listarray = new Object[sz]; }

public void clear() { top = 0; }


// Clear all Objects
public void push(Object it)
// Push onto stack
{ Assert.notFalse(top < size, "Stack overflow"); listarray[top++] = it; }
public Object pop()
// Pop Object from top
{ Assert.notFalse(!isEmpty(), "Empty stack"); return listarray[--top]; }
public Object topValue()
// Return top Object
{ Assert.notFalse(!isEmpty(), "Empty stack"); return listarray[top-1]; }
public boolean isEmpty() { return top == 0; }

size
top
E.G.M. Petrakis

size

stacks, queues

Dynamic Memory Implementation


Simplified version of the linked list
implementation
the head and tail pointers of the list
implementation are not used
top

E.G.M. Petrakis

stacks, queues

class LStack implements Stack {

// Linked stack class

private Link top; // Pointer to list header


public LStack() { setup(); }
private void setup()
{ top = null; }

// Constructor
// Initialize stack
// Create header node

public void clear() { top = null; }


// Clear stack
public void push(Object it)
// Push Object onto stack
{ top = new Link(it, top); }
public Object pop() {
// Pop Object from top
Assert.notFalse(!isEmpty(), "Empty stack");
Object it = top.element();
top = top.next();
return it;
}
public Object topValue()
// Get value of top Object
{ Assert.notFalse(!isEmpty(), "No top value"); return top.element(); }
public boolean isEmpty()
// True if stack is empty
{ return top == null; }
} // Linked stack class
E.G.M. Petrakis

stacks, queues

Applications
Checking mathematical expressions
Equal number of left/right (, {, [, ), }, ]

7 ((X * ((X + Y)/(J 3) + Y)/(4 2.5))

((A+ B)
)A + B C)
- (A + B)) CA
-

E.G.M. Petrakis

stacks, queues

wrong

Algorithm
Read the expression from left to right
p: next symbol in expression
Repeat until (empty(stack) ) {
read(p);
if p = ( or { or [ then push(stack,p);
loop;
if p = ) or } or ] then c = pop(stack);
if c != p then error!!
}
if (not empty(stack) ) then error!!

E.G.M. Petrakis

stacks, queues

{x + (y [a + b]) * c [(d + e)]}

[
(
(
(

{x + (y [a + b]) * c [(d + e)]}/(h (j (k [

(
{x + (y [a + b]) * c [(d + e)]}/(h (j (k [l n]))

{x + (y [a + b]) * c [(d + e)]}/(h (j (k [l n])))


E.G.M. Petrakis

stacks, queues

More Applications
Evaluation of arithmetic expressions:
convert infix to postfix or prefix
evaluate postfix or prefix expression

infix, prefix, postfix: refer to the


relative position of the operator with
respect to the operands
infix : A+B
prefix : +AB
postfix : AB+

E.G.M. Petrakis

stacks, queues

10

Infix to Postfix or Prefix


Read from left to right
First convert operations of higher precedence

parenthesis have the highest precedence


^ have precedence over
*, / have the same precedence but higher than
+, - which all have the same precedence

The converted prefix or postfix part is treated as


a single operand
If all operators have the same precedence then
convert from left to right
E.G.M. Petrakis

stacks, queues

11

Infix to Postfix or Prefix


A+B*C

: * > +

A+(B*C) : equivalent
+(C*) : B*C to postfix
ABC*+ : postfix

(A+B)*C : () > *

(AB+)*C : A+B to postfix


(AB+)C* : (AB+)*C to postfix
AB+C* : postfix

Postfix and Prefix have no parenthesis !!

E.G.M. Petrakis

stacks, queues

12

Infix to Postfix or Prefix


A+B-C

: +C-

postfix

(A+B)*(C-D) : AB+CD-*
$*C-D+E/F/(G+H) : AB$C*D-EF/GH+/+
A-B/(C*D$E) : ABCDE$*/-

A+B-C

: -+ABC

prefix

(A+B)*(C-D) : *+AB-CD
A$B*C-D+E/F/(G+H) : +-*$ABCD//EF+GH
A-B/(C*D$E) : -A/B*C$DE
E.G.M. Petrakis

stacks, queues

13

Convert infix to postfix


Read expression from left to right

output operands
push operators to stack
higher precedence operators must be above lower
precedence operators
before pushing an operator into the stack check the
precedence of operators already in the stack

if operator in stack has higher precedence output this


operator and then insert the current operator in the stack
(, [, { have higher precedence, push in stack
if ), ], } pop stack until (, [, { is found
dont output (, [, {, ), ], }

E.G.M. Petrakis

stacks, queues

14

Infix to Postfix Example


(A + B)*C

push ( in stack
output A
push + in stack
output B
dont push ), pop all operators
output +, ignore (, )
* push in stack
output C
output *

E.G.M. Petrakis

stacks, queues

15

Example: (A + B)*C
Symbol
(
A
+
B
)
*

E.G.M. Petrakis

Postfix
A
A
AB
AB+
AB+
AB+C
AB+C*

stacks, queues

Stack
(
(
(+
(+
*
*

16

Algorithm
stack = NULL;
while (not end of input) {
symbol = read next symbol;
if (symbol == operand) output(symbol);
else {

while(!empty(stack) && (preced (stack(top)) > preced(symbol))


{ top symbol = pop(stack); output(top symbol); }
push(stack, symbol);
}

}
while not_empty(stack) {
top symbol = pop(stack);
output(top symbol);
}
E.G.M. Petrakis

stacks, queues

17

Evaluation of Postfix
While (not end of expression) {
read symbols from left to right;
result = 0
if (symbol == operand) push (stack);
else {
operand1 = pop(stack);
operand2 = pop(stack);
result = operand1 operator operand2;
push(stack, result);
}
}
result = pop(stack);
E.G.M. Petrakis

stacks, queues

18

Postfix: 6 2 3 + - 3 8 2 / + * 2 $ 3 +
Symbol Operand1Operand2 Value stack Operand
6
6
6,2
2
6,2,3
3
6,5
5
3
2
+
1
1
5
6
1,3
1
5
6
3
1,3,8
1
5
6
8
1,3,8,2
1
5
6
2
1,3,4
4
2
8
/
1,7
7
4
3
+
7
7
7
1
*
7,2
7
7
1
2
49
49
2
7
$
49,3
49
2
7
3
E.G.M. Petrakis
52
3stacks, queues 52
49
+

19

Queue
Queue elements may only be inserted
at the rear and removed from the

front

restricted form of list


FIFO: first in first out
insert: enqueue operation
remove: dequeue operator

E.G.M. Petrakis

stacks, queues

20

front

A
B

E.G.M. Petrakis

B
C

rear
C

stacks, queues

enqueue (queue, D)
dequeue (queue)

21

Array Implementation
If the elements are the first 43
2
n elements of array and the
x
1
front element is at position 0 0 x
enqueue requires (1) operations but,
dequeue requires (n) operations (all
elements must be shifted)
Condition of empty queue?
E.G.M. Petrakis

stacks, queues

22

Front: next available (empty) position


Rear: last position
Condition of empty queue: rear = front
Initial values: rear=fron =LIST_SIZE - 1
4
3
2
1
0
4
3
2
1
0

front = 4
rear = 4

E.G.M. Petrakis

front = 4
rear = 0

front points to the position


proceeding the first element

input A

stacks, queues

23

4
3
2
1
0

C
B

front = 4
rear = 2

4
3
2
1
0

D
C
B

front = 4
rear = 3

4
3
2
1
0

E
D
C
B

E.G.M. Petrakis

front = 4
rear = 4

The condition of empty


queue is true but the
queue is not empty
E cannot be inserted:
The last array position
must be left empty:

stacks, queues

24

4
3
2
1
0

4
3
2
1
0

D
C
B

Delete
front = 0
rear = 3

Delete B
D
C

E.G.M. Petrakis

front = 1
rear = 3

4
3
2
1
0

stacks, queues

E
D
C

Insert E, F

Circular list
front = 2
rear = 0

25

Queue ADT
public interface Queue {

public
public
public
public
public

// Queue ADT

void clear();
// Remove all Objects from queue
void enqueue(Object it); // Enqueue Object at rear of queue
Object dequeue();
// Dequeue Object from front of queue
Object firstValue();
// Return value of top Object
boolean isEmpty();
// Return TRUE if stack is empty

E.G.M. Petrakis

stacks, queues

26

class AQueue implements Queue { // Array-based queue class


private static final int defaultSize = 10;
private int size;
// Maximum size of queue
private int front;
// Index prior to front item
private int rear;
// Index of rear item
private Object [] listArray; // Array holding Objects
AQueue() { setup(defaultSize); } // Constructor: default size
AQueue(int sz) { setup(sz); } // Constructor: set size
void setup(int sz)
// Initialize queue
{ size = sz+1; front = rear = 0; listArray = new Object[sz+1]; }
public void clear()
{ front = rear = 0; }

size
front
rear
E.G.M. Petrakis

// Remove all Objects from queue

size

stacks, queues

27

public void enqueue(Object it) { // Enqueue Object at rear


Assert.notFalse(((rear+1) % size) != front, "Queue is full");
rear = (rear+1) % size;
// Increment rear (in circle)
listArray[rear] = it;
}
public Object dequeue() {
// Dequeue Object from front
Assert.notFalse(!isEmpty(), "Queue is empty");
front = (front+1) % size; // Increment front
return listArray[front];
// Return value
}
public Object firstValue() { // Return value of front Object
Assert.notFalse(!isEmpty(), "Queue is empty");
return listArray[(front+1) % size];
}
public boolean isEmpty()
{ return front == rear; }
} // class AQueue
E.G.M. Petrakis

// Return true if queue is empty

stacks, queues

28

Dynamic Memory Implementation


Simple adaptation of the linked list implementation
current always points to the first element
the head pointer of the list implementation is not used

front
rear

E.G.M. Petrakis

stacks, queues

29

class LQueue implements Queue {


private Link front;
private Link rear;

// Linked queue class

// Pointer to front node


// Pointer to rear node

public LQueue() { setup(); }


public LQueue(int sz) { setup(); }

// Constructor
// Constuctor: Ignore sz

private void setup()


{ front = rear = null; }

// Initialize queue

// Remove all Objects from queue


public void clear() { front = rear = null; }
public void enqueue(Object it) {
// Enqueue Object at rear of queue
if (rear != null) {
// Queue not empty: add to end
rear.setNext(new Link(it, null));
rear = rear.next();
}
else front = rear = new Link(it, null); // Empty queue
}
E.G.M. Petrakis

stacks, queues

30

public Object dequeue() {


// Dequeue Object from front
Assert.notFalse(!isEmpty()); // Must be something to dequeue
Object it = front.element(); // Store dequeued Object
front = front.next();
// Advance front
if (front == null) rear = null; // Dequeued last Object
return it;
// Return Object
}
public Object firstValue()
// Return value of top Object
{ Assert.notFalse(!isEmpty()); return front.element(); }
public boolean isEmpty()
{ return front == null; }

// Return true if queue is empty

} // classes LQueue

E.G.M. Petrakis

stacks, queues

31

Priority Queue
Ascending: elements in any order but
dequeue removes the minimum
Descending: dequeue removes the
maximum

E.G.M. Petrakis

stacks, queues

32

Example: Dequeue
5
4
3
2
1
5
4
3
2
1

D
G

front = 5
rear = 4

ascending

D
G

E.G.M. Petrakis

front = 5
rear = 4

5
4
3
2
1

stacks, queues

descending

front = 5
rear = 4

?
33

Array Implementation
Problem: dequeue creates
empty slots
Solution(1): move elements:
(n) operations on dequeue

Solution(2): store elements


in ascending (descending)
order: (n) operations on

enqueue

E.G.M. Petrakis

5
4
3
2
1
5
4
3
2
1

stacks, queues

D
G

5
4
3
2
1

E
D

5
4
3
2
1

E
D

34

Вам также может понравиться