Chapter 4 Stacks Queues

download Chapter 4 Stacks Queues

of 55

Transcript of Chapter 4 Stacks Queues

  • 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