Upload
godson-dsilva
View
234
Download
0
Embed Size (px)
Citation preview
7/31/2019 Chapter 4 Stacks Queues
1/55
Chapter 4Stacks, Queues, and
Recursion
7/31/2019 Chapter 4 Stacks Queues
2/55
Using Recursion
7/31/2019 Chapter 4 Stacks Queues
3/55
Recall the Recursion Pattern Recursion: when a method calls itself
Classic example--the factorial function:
n! = 1 2 3 (n-1) n
Recursive definition:
As a Java method:// recursive factorial function
public static int recursiveFactorial(int n) {
if (n == 0) return 1; // basis case
else return n * recursiveFactorial(n-1); // recursive case
}
== elsenfn
nnf)1(
0if1)(
7/31/2019 Chapter 4 Stacks Queues
4/55
Linear Recursion Test for base cases.
Begin by testing for a set of base cases (thereshould be at least one).
Every possible chain of recursive calls musteventually reach a base case, and the handling of
each base case should not use recursion. Recur once.
Perform a single recursive call. (This recursive stepmay involve a test that decides which of several
possible recursive calls to make, but it shouldultimately choose to make just one of these callseach time we perform this step.)
Define each possible recursive call so that it makes
progress towards a base case.
7/31/2019 Chapter 4 Stacks Queues
5/55
A Simple Example of LinearRecursion
Algorithm LinearSum(A, n):Input:
A integer array A and an integer n =1, such that A has at least nelements
Output:The sum of the first nintegers in A
if n= 1 thenreturn A[0]
else
return LinearSum(A, n -1) + A[n -1]
Example recursion trace:
LinearSum(A,5)
LinearSum(A,1)
LinearSum(A,2)
LinearSum(A,3)
LinearSum(A,4)
call
call
call
call return A[0] = 4
return 4 + A[1] = 4 + 3 = 7
return 7 + A[2] = 7 + 6 = 13
return 13 + A[3] = 13 + 2 = 15
call return 15 + A[4] = 15 + 5 = 20
7/31/2019 Chapter 4 Stacks Queues
6/55
Reversing an Array
Algorithm ReverseArray(A, i, j):Input:An array A and nonnegative integer
indices iand j
Output:The reversal of the elements in Astarting at index iand ending at j
if i < jthenSwap A[i] and A[j]
ReverseArray(A, i+ 1, j -1)
return
7/31/2019 Chapter 4 Stacks Queues
7/55
Defining Arguments for Recursion
In creating recursive methods, it is important todefine the methods in ways that facilitaterecursion.
This sometimes requires we define additionalparamaters that are passed to the method.
For example, we defined the array reversal
method as ReverseArray(A, i, j), notReverseArray(A).
7/31/2019 Chapter 4 Stacks Queues
8/55
Computing Powers
The power function, p(x,n)=xn
, can be definedrecursively:
This leads to an power function that runs in O(n)time (for we make n recursive calls).
We can do better than this, however.
==
else)1,(
0if1),(
nxpx
nnxp
7/31/2019 Chapter 4 Stacks Queues
9/55
Recursive Squaring We can derive a more efficient linearly
recursive algorithm by using repeated squaring:
For example,24= 2(4/2)2 = (24/2)2 = (22)2 = 42 = 16
25= 21+(4/2)2 = 2(24/2)2 = 2(22)2 = 2(42) = 3226= 2(6/2)2 = (26/2)2 = (23)2 = 82 = 64
27= 21+(6/2)2 = 2(26/2)2 = 2(23)2 = 2(82) = 128.
>
>
=
=
evenis0if
oddis0if
0if
)2/,(
)2/)1(,(
1
),(2
2
x
x
x
nxp
nxpxnxp
7/31/2019 Chapter 4 Stacks Queues
10/55
A Recursive Squaring Method
Algorithm Power(x, n):
Input:A number xand integer n =0
Output:The value xn
if n= 0 then
return 1if nis odd then
y =Power(x, (n -1)/2)
return x y yelse
y =Power(x, n/2)
return y y
7/31/2019 Chapter 4 Stacks Queues
11/55
Analyzing the Recursive SquaringMethod
Algorithm Power(x, n):
Input:A number xandinteger n =0Output:The value xn
if n= 0 thenreturn 1
if nis odd theny =Power(x, (n -1)/2)
return x y y else
y =Power(x, n/2)return y y
It is important that weused a variable twice hererather than calling themethod twice.
Each time we make arecursive call we halve the
value of n; hence, we makelog n recursive calls. Thatis, this method runs inO(log n) time.
7/31/2019 Chapter 4 Stacks Queues
12/55
Tail Recursion Tail recursion occurs when a linearly recursive
method makes its recursive call as its last step. The array reversal method is an example. Such methods can be easily converted to non-
recursive methods (which saves on some resources).
Example:Algorithm IterativeReverseArray(A, i, j):
Input:An array A and nonnegative integer indices iandjOutput:The reversal of the elements in A starting at index i
and ending atj
while i < jdoSwap A[i] and A[j]i = i+ 1j = j -1
return
7/31/2019 Chapter 4 Stacks Queues
13/55
Binary Recursion ( 4.1.2)
Binary recursion occurs whenever there aretwo recursive calls for each non-base case.
Example: the DrawTicks method for drawing
ticks on an English ruler.
7/31/2019 Chapter 4 Stacks Queues
14/55
A Binary Recursive Method forDrawing Ticks// draw a tick with no label
public static void drawOneTick(int tickLength) { drawOneTick(tickLength, - 1); }// draw one tick
public static void drawOneTick(int tickLength, int tickLabel) {for (int i = 0; i < tickLength; i++)
System.out.print("-");if (tickLabel >= 0) System.out.print(" " + tickLabel);
System.out.print("\n");}public static void drawTicks(int tickLength) { // draw ticks of given length
if (tickLength > 0) { // stop when length drops to 0drawTicks(tickLength- 1); // recursively draw left ticksdrawOneTick(tickLength); // draw center tickdrawTicks(tickLength- 1); // recursively draw right ticks
}}public static void drawRuler(int nInches, int majorLength) { // draw ruler
drawOneTick(majorLength, 0); // draw tick 0 and its labelfor (int i = 1; i
7/31/2019 Chapter 4 Stacks Queues
15/55
Another Binary Recusive Method Add all the numbers in an integer array A:
Algorithm BinarySum(A, i, n):Input:An array A and integers iand nOutput:The sum of the nintegers in A starting at index iif n= 1 thenreturn A[i]
return BinarySum(A, i, n/2) + BinarySum(A, i+ n/2, n/2)
Example trace:
3, 1
2, 2
0, 4
2, 11, 10, 1
0, 8
0, 2
7, 1
6, 2
4, 4
6, 15, 1
4, 2
4, 1
7/31/2019 Chapter 4 Stacks Queues
16/55
Computing Fibanacci Numbers
Fibonacci numbers are defined recursively:F0 = 0F1 = 1
Fi= Fi-1+ Fi-2 for i >1.
As a recursive algorithm (first attempt):Algorithm BinaryFib(k):
Input:Nonnegative integer k
Output:The kth Fibonacci number Fkif k =1 then
return k
else
return BinaryFib(k -1) + BinaryFib(k -2)
7/31/2019 Chapter 4 Stacks Queues
17/55
Analyzing the Binary RecursionFibonacci Algorithm
Let nk
denote number of recursive calls made byBinaryFib(k). Then n0 = 1 n1 = 1 n2 = n1 + n0 + 1 = 1 + 1 + 1 = 3
n3 = n2 + n1 + 1 = 3 + 1 + 1 = 5 n4 = n3 + n2 + 1 = 5 + 3 + 1 = 9 n5 = n4 + n3 + 1 = 9 + 5 + 1 = 15 n6 = n5 + n4 + 1 = 15 + 9 + 1 = 25
n7 = n6 + n5 + 1 = 25 + 15 + 1 = 41 n8 = n7 + n6 + 1 = 41 + 25 + 1 = 67.
Note that the value at least doubles for every other
value of nk. That is, nk > 2k/2
. It is exponential!
7/31/2019 Chapter 4 Stacks Queues
18/55
A Better Fibonacci Algorithm Use linear recursion instead:
Algorithm LinearFibonacci(k):Input:A nonnegative integer k
Output:Pair of Fibonacci numbers (Fk, Fk-1)
if k =1 then
return (k, 0)else
(i, j) = LinearFibonacci(k -1)
return (i+j, i)
Runs in O(k) time.
7/31/2019 Chapter 4 Stacks Queues
19/55
Stacks
7/31/2019 Chapter 4 Stacks Queues
20/55
Abstract Data Types (ADTs) An abstract data
type (ADT) is anabstraction of a datastructure
An ADT specifies:
Data stored Operations on the
data
Error conditionsassociated withoperations
Example: ADT modeling a
simple stock trading system The data stored are buy/sell
orders
The operations supported are
order buy(stock, shares, price)
order sell(stock, shares, price)
void cancel(order)
Error conditions: Buy/sell a nonexistent stock
Cancel a nonexistent order
7/31/2019 Chapter 4 Stacks Queues
21/55
The Stack ADT The Stack ADT stores
arbitrary objects Insertions and deletions
follow the last-in first-outscheme
Think of a spring-loadedplate dispenser
Main stack operations: push(object): inserts an
element object pop(): removes and
returns the last insertedelement
Auxiliary stack
operations: object top(): returns the
last inserted elementwithout removing it
integer size(): returns thenumber of elementsstored
boolean isEmpty():
indicates whether noelements are stored
7/31/2019 Chapter 4 Stacks Queues
22/55
Stack Interface in Java Java interface
corresponding to ourStack ADT
Requires the definitionof class
EmptyStackException Different from the
built-in Java classjava.util.Stack
public interface Stack {
public int size();public boolean isEmpty();
public Object top()throws EmptyStackException;
public void push(Object o);
public Object pop()throws
EmptyStackException;}
7/31/2019 Chapter 4 Stacks Queues
23/55
Exceptions Attempting the execution
of an operation of ADTmay sometimes cause anerror condition, called anexception
Exceptions are said to bethrown by an operationthat cannot be executed
In the Stack ADT,
operations pop and topcannot be performed if thestack is empty
Attempting the execution
of pop or top on an emptystack throws anEmptyStackException
7/31/2019 Chapter 4 Stacks Queues
24/55
Applications of Stacks
Direct applications Page-visited history in a Web browser
Undo sequence in a text editor
Chain of method calls in the Java Virtual Machine
Indirect applications Auxiliary data structure for algorithms
Component of other data structures
7/31/2019 Chapter 4 Stacks Queues
25/55
Method Stack in the JVM The Java Virtual Machine
(JVM) keeps track of the chain
of active methods with a stack When a method is called, the
JVM pushes on the stack aframe containing Local variables and return value
Program counter, keeping track ofthe statement being executed
When a method ends, its frameis popped from the stack andcontrol is passed to the methodon top of the stack
Allows for recursion
main() {int i = 5;
foo(i);}
foo(int j) {int k;k = j+1;bar(k);}
bar(int m) {}
barPC = 1m = 6
fooPC = 3j = 5k = 6
mainPC = 2i = 5
7/31/2019 Chapter 4 Stacks Queues
26/55
Array-based Stack A simple way of
implementing theStack ADT uses anarray
We add elements
from left to right A variable keeps
track of the index ofthe top element
S0 1 2 t
Algorithm size()return t+ 1
Algorithm pop()if isEmpty() then
throw EmptyStackException
elset t 1return S[t+ 1]
7/31/2019 Chapter 4 Stacks Queues
27/55
Array-based Stack (cont.) The array storing the
stack elements maybecome full
A push operation willthen throw a
FullStackException Limitation of the array-
based implementation
Not intrinsic to theStack ADT
S0 1 2 t
Algorithm push(o)if t= S.length 1 then
throw FullStackExceptionelse
t
t+ 1S[t] o
7/31/2019 Chapter 4 Stacks Queues
28/55
Performance and Limitations Performance
Letn be the number of elements in the stack
The space used is O(n)
Each operation runs in time O(1)
Limitations
The maximum size of the stack must be defined apriori and cannot be changed
Trying to push a new element into a full stackcauses an implementation-specific exception
7/31/2019 Chapter 4 Stacks Queues
29/55
Array-based Stack in Javapublic class ArrayStack
implements Stack {// holds the stack elementsprivate Object S[ ];
// index to top element
private int top = -1;
// constructorpublic ArrayStack(int
capacity) {S = new
Object[capacity]);}
public Object pop()
throws EmptyStackException {if isEmpty()throw new
EmptyStackException(Empty stack: cannot pop);
Object temp = S[top];// facilitates garbage collectionS[top] = null;top = top 1;
return temp;}
7/31/2019 Chapter 4 Stacks Queues
30/55
Parentheses Matching
Each (, {, or [ must be paired with amatching ), }, or [
correct: ( )(( )){([( )])}
correct: ((( )(( )){([( )])} incorrect: )(( )){([( )])}
incorrect: ({[ ])}
incorrect: (
7/31/2019 Chapter 4 Stacks Queues
31/55
Parentheses Matching AlgorithmAlgorithm ParenMatch(X,n):
Input:An array Xof ntokens, each of which is either a grouping symbol, a
variable, an arithmetic operator, or a numberOutput:true if and only if all the grouping symbols in Xmatch
Let Sbe an empty stack
for i=0 to n-1 do
if X[i] is an opening grouping symbol then
S.push(X[i])else if X[i] is a closing grouping symbol then
if S.isEmpty() then
return false {nothing to match with}
if S.pop() does not match the type of X[i] then
return false {wrong type}if S.isEmpty() then
return true {every symbol matched}
else
return false {some symbols were never matched}
7/31/2019 Chapter 4 Stacks Queues
32/55
Computing Spans (not in book) We show how to use a stack
as an auxiliary data structurein an algorithm
Given an an array X, thespan S[i] of X[i] is the
maximum number ofconsecutive elements X[j]immediately preceding X[i]and such that X[j] X[i]
Spans have applications tofinancial analysis E.g., stock at 52-week high
13211
25436X
S
0
12
3
4
5
6
7
0 1 2 3 4
7/31/2019 Chapter 4 Stacks Queues
33/55
Quadratic AlgorithmAlgorithm spans1(X, n)
Input array Xof nintegers
Output array Sof spans of X #
S new array of nintegers nfor i 0 to n 1 do n
s 1 n
while s i X[i- s] X[i] 1 + 2 + + (n 1)s s+ 1 1 + 2 + + (n 1)
S[i] s nreturn S 1
Algorithmspans1 runs in O(n2) time
7/31/2019 Chapter 4 Stacks Queues
34/55
Computing Spans with a Stack We keep in a stack the
indices of the elementsvisible when lookingback
We scan the array from
left to right Let ibe the current index
We pop indices from thestack until we find indexj
such that X[i] < X[j]
We set S[i] i-j
We push xonto the stack
0
1
23
4
5
6
7
0 1 2 3 4 5 6 7
7/31/2019 Chapter 4 Stacks Queues
35/55
Linear AlgorithmAlgorithm spans2(X, n) #
S new array of nintegers n
A new empty stack 1for i 0 to n 1 do n
while ( A.isEmpty()X[A.top()] X[i] ) do n
A.pop() nif A.isEmpty() then n
S[i] i+ 1 nelse
S[i]
i- A.top() nA.push(i) n
return S 1
Each index of thearray Is pushed into the
stack exactly one
Is popped fromthe stack at most
once The statements in
the while-loop areexecuted at most
ntimes Algorithm spans2
runs in O(n) time
7/31/2019 Chapter 4 Stacks Queues
36/55
Queues
7/31/2019 Chapter 4 Stacks Queues
37/55
The Queue ADT The Queue ADT stores arbitrary
objects
Insertions and deletions followthe first-in first-out scheme
Insertions are at the rear of thequeue and removals are at the
front of the queue Main queue operations:
enqueue(object): inserts anelement at the end of the queue
object dequeue(): removes andreturns the element at the front
of the queue
Auxiliary queueoperations: object front(): returns the
element at the front withoutremoving it
integer size(): returns the
number of elements stored boolean isEmpty():
indicates whether noelements are stored
Exceptions Attempting the execution ofdequeue or front on anempty queue throws anEmptyQueueException
7/31/2019 Chapter 4 Stacks Queues
38/55
Queue ExampleOperation Output Q
enqueue(5) (5)
enqueue(3) (5, 3)dequeue() 5 (3)
enqueue(7) (3, 7)
dequeue() 3 (7)
front() 7 (7)
dequeue() 7 ()
dequeue() error ()
isEmpty() true ()
enqueue(9) (9)
enqueue(7) (9, 7)size() 2 (9, 7)
enqueue(3) (9, 7, 3)
enqueue(5) (9, 7, 3, 5)
dequeue() 9 (7, 3, 5)
7/31/2019 Chapter 4 Stacks Queues
39/55
Applications of Queues
Direct applicationsWaiting lists, bureaucracy
Access to shared resources (e.g., printer)
Multiprogramming Indirect applications
Auxiliary data structure for algorithms
Component of other data structures
7/31/2019 Chapter 4 Stacks Queues
40/55
Array-based Queue Use an array of sizeNin a circular fashion
Two variables keep track of the front and rearf index of the front element
r index immediately past the rear element
Array locationr is kept empty
Q
0 1 2 rf
normal configuration
Q
0 1 2 fr
wrapped-around configuration
7/31/2019 Chapter 4 Stacks Queues
41/55
Queue Operations We use the
modulo operator(remainder ofdivision)
Algorithm size()
return (N- f+ r) mod N
Algorithm isEmpty()return (f= r)
Q
0 1 2 rf
Q
0 1 2 fr
7/31/2019 Chapter 4 Stacks Queues
42/55
Queue Operations (cont.)Algorithm enqueue(o)
if size() = N 1 then
throw FullQueueExceptionelse
Q[r] or (r+ 1) mod N
Operation enqueuethrows an exception ifthe array is full
This exception isimplementation-
dependent
Q
0 1 2 rf
Q
0 1 2 fr
7/31/2019 Chapter 4 Stacks Queues
43/55
Queue Operations (cont.) Operation dequeue
throws an exceptionif the queue is empty
This exception isspecified in thequeue ADT
Algorithm dequeue()if isEmpty() then
throw EmptyQueueExceptionelse
o Q[f]f (f+ 1) mod N
return o
Q
0 1 2 rf
Q
0 1 2 fr
7/31/2019 Chapter 4 Stacks Queues
44/55
Queue Interface in Java Java interface
corresponding to ourQueue ADT
Requires the definitionof class
EmptyQueueException No corresponding built-
in Java class
public interface Queue {
public int size();public boolean isEmpty();
public Object front()throws EmptyQueueException;
public void enqueue(Object o);
public Object dequeue()throws
EmptyQueueException;}
7/31/2019 Chapter 4 Stacks Queues
45/55
Application: Round RobinSchedulers We can implement a round robin scheduler using a
queue, Q, by repeatedly performing the followingsteps:
1. e = Q.dequeue()
2. Service element e
3. Q.enqueue(e)
The Queue
Shared
Service
1. Deque the
next element
3. Enqueue the
serviced element
2. Service the
next element
7/31/2019 Chapter 4 Stacks Queues
46/55
Linked Lists
7/31/2019 Chapter 4 Stacks Queues
47/55
Singly Linked List ( 4.4.1) A singly linked list is a
concrete data structure
consisting of a sequenceof nodes
Each node stores element
link to the next node
next
elem
node
A B C D
7/31/2019 Chapter 4 Stacks Queues
48/55
The Node Class for List Nodespublic class Node {
// Instance variables:private Object element;private Node next;
/** Creates a node with null references to its element and next node. */public Node() {
this(null, null);}
/** Creates a node with the given element and next node. */public Node(Object e, Node n) {
element = e;next = n;
}// Accessor methods:public Object getElement() {
return element;}public Node getNext() {
return next;
}// Modifier methods:public void setElement(Object newElem) {
element = newElem;}public void setNext(Node newNext) {
next = newNext;
}}
7/31/2019 Chapter 4 Stacks Queues
49/55
Inserting at the Head1. Allocate a new node
2. Insert new element3. Have new node point
to old head
4. Update head to pointto new node
7/31/2019 Chapter 4 Stacks Queues
50/55
Removing at the Head
1. Update head to pointto next node in thelist
2. Allow garbagecollector to reclaimthe former first node
7/31/2019 Chapter 4 Stacks Queues
51/55
Inserting at the Tail1. Allocate a new
node2. Insert new element
3. Have new node
point to null4. Have old last node
point to new node
5. Update tail to pointto new node
7/31/2019 Chapter 4 Stacks Queues
52/55
Removing at the Tail
Removing at the tailof a singly linked listis not efficient!
There is no constant-time way to updatethe tail to point to theprevious node
7/31/2019 Chapter 4 Stacks Queues
53/55
Stack with a Singly Linked List We can implement a stack with a singly linked list
The top element is stored at the first node of the list The space used is O(n) and each operation of the
Stack ADT takes O(1) time
t
nodes
elements
7/31/2019 Chapter 4 Stacks Queues
54/55
Queue with a Singly Linked List We can implement a queue with a singly linked list
The front element is stored at the first node
The rear element is stored at the last node
The space used is O(n) and each operation of theQueue ADT takes O(1) time
f
r
nodes
elements
7/31/2019 Chapter 4 Stacks Queues
55/55
Acknowledgement Data Structures and Algorithm in JAVA:
Michael T. Goodrich and Roberto Tamassia www.datastructures.net