stacks queues

17
M.A. Eljinini, PhD Data Structures Linear Data Structures Stacks & Queues By Dr. Mohammad Ali H. Eljinini M.A. Eljinini, PhD Linear Data Structures Are collections of items arranged in a straight line (i.e. in array, or maybe. . . linked list!) Stacks and Queues are linear data structures, where data can be stored linearly! However: Some rules are applied when adding and removing items from Stacks and Queues. So, let us start with Stacks!

Upload: gobara-dhan

Post on 26-Nov-2015

3 views

Category:

Documents


0 download

DESCRIPTION

stack and queues

TRANSCRIPT

  • M.A. Eljinini, PhD

    Data Structures

    Linear Data Structures

    Stacks & Queues

    By

    Dr. Mohammad Ali H. Eljinini

    M.A. Eljinini, PhD

    Linear Data Structures

    Are collections of items arranged in a straight line (i.e. in array, or maybe. . . linked list!)

    Stacks and Queues are linear data structures, where data can be stored linearly!

    However:

    Some rules are applied when adding and removing items from Stacks and Queues.

    So, let us start with Stacks!

  • M.A. Eljinini, PhD

    Stacks

    A stack is a container where the last item is added (pushed) must comes out first (popped)

    So it is a Last In First Out

    LIFO

    Example:

    A long, narrow, one-end, Cars Park:

    B C

    - Car A must have entered first, then B, and last C!

    - Last one in is C, must be the first to come out.

    - A is the last to come out, since the first pushed in.

    A

    M.A. Eljinini, PhD

    Stacks another example

    Look at this code (decimal-to-binary):

    K = 13;

    While ( k != 0 ){

    System.out.print(k%2); // print 0s and 1s

    k = k /2;

    }

    What is wrong with this code? 0s and 1s are printed in reverse order !!

    One solution is to use Stacks !! Push 0s and 1s inside a stack (i.e. replace the print with

    push)

    Then in another loop, start popping and printing !!

    So, Last item entered in the stack, will be removed and printed first, then the one before last, until we get to the first one entered.

    Output:1011

  • M.A. Eljinini, PhD

    Stacks another example

    Version 2 correct output using a stack:

    k = 13;

    While ( k != 0 ){

    s.push(k%2); // push remainders in stack S

    k = k /2;

    } While( !s.empty() )

    System.out.print( s.pop() ); // pop items from s and print

    Correct Output:1101

    0 11 1

    1 1 0 1

    1

    2Stack S

    M.A. Eljinini, PhD

    Stack: Array-Based Representation Now, we need to define a Data Structure of the

    Stack.

    Then, we need to write the operations (i.e. methods) push, pop, empty, and init.

    public class Stack{ // A new class Stack

    private int top; // top: index of last item entered

    private int items[ ] = new int[10];

    }

    Stack (a new class - a class )

    itemstop

  • M.A. Eljinini, PhD

    Stack: Array-Base Representation:

    Now, we can declare S of Type Stack:

    Stack S;

    Then, we can store a 0 in top: (remember top is int )

    top = 0;

    And (for example) A in first location of array items:

    items[0] = A;

    itemstop

    S

    S

    A0itemstop

    M.A. Eljinini, PhD

    Stack: Array-Base Representation

    or, we can declare S as a reference of type Stack:

    Stack S;

    Then we can use new to instantiate a stack:

    S = new Stack();

    And assign values:

    top = 0;

    items[0] = A;

    S

    A0itemstop

    S

  • M.A. Eljinini, PhD

    Stack: Operations

    But, what did happen to LIFO??

    We need now to write functions push(), pop(), init(),

    and empty(), so we can access the Stack ONLY via

    these operations ! Lets start with init():

    void init( ) // Used to initialize the stack

    {

    top = -1; // if top has -1 stack is empty !!

    }

    And empty():

    boolean empty( ) // return true if empty !

    {

    return (top == -1); // == logical operation

    } // not assignment !!

    M.A. Eljinini, PhD

    Stack: Operations

    And push() to add new item to the stack:

    public void push( itemType x) // x: item to add

    {

    if( top == MAX-1 ){ // if top reached max size

    System.out.println(Error: Stack is full);

    }

    else

    // first, increment top by 1, the next empty slot.

    // then insert x inside items at location [top]

    items[ ++top] = x;

    }

  • M.A. Eljinini, PhD

    Stack: Operations

    Finally, pop() to remove and return last item added in the stack:

    itemType pop( ) // Return type of itemType

    {

    if( s.empty() ){ // if empty we cannot remove items

    System.out.println(Error: Stack is empty);

    }

    else

    // first, decrement top by 1,to the last full slot.

    // then return the value in that slot

    return ( items[--top] );

    }

    M.A. Eljinini, PhD

    Stack : OperationsNotes:1. Always, stacks are accessed via the methods push()

    pop(), init(), and empty() only!

    This way we can insure the when we use pop(), the

    last item inserted will be the one to be removed

    and returned.

    In other words, these functions control the

    mechanisms in which the stack operates

    2. To change the size of the stack, change the value

    of MAX.

    3. To use stack with other types than chars, change

    the type itemType to any type you may need

    (i.e. floats, arrays, other structures, etc.)

  • M.A. Eljinini, PhD

    Stack: Linked-Based Representation In Linked-Based Stack, array items is replaced

    with a linked list! And, Stack functions need to be re-implemented to work with the linked list

    public class StackNode{

    private int item; // Holds the item to be pushed

    private Stack next; // Referes to next node

    // implement set and get for item and next

    } // It is just a node

    item link

    M.A. Eljinini, PhD

    Stack: Linked-Based Representationpublic class stack{

    private StackNode L;

    public void push(int x)

    { // create new node and insert in L before first }

    public int pop()

    { // return data in first node and move it }

    } item link

    B

    L item link

    NULLCA

    item link

    When push: s.push(A); Add the new node at the Beginning

    When pop: x=s.pop();Return the item in this nodethen remove it from the list.

    The implementation of these functions are left as exercise

  • M.A. Eljinini, PhD

    Exercises - Stacks

    1. Implement a linked-based stack complete with the

    operations.

    2. Write a complete program Decimal-to-Binary,

    using the stack implemented in 1 above.

    3. Write a program to reverse the order of nodes on a

    list using a stack.

    4. Think of other uses for stacks and list them.

    M.A. Eljinini, PhD

    Queues

    A Queue is a container where the first item inserted must comes out first. (a waiting line)

    So it is a First in First Out

    FIFO

    Example:

    A long, narrow, open-ends, Cars Park:

    B C

    - Car A must have entered first, then B, and last C!

    - First one in is A, must be the first to come out.

    - C is the last to come out, since the Last one in.

    A

  • M.A. Eljinini, PhD

    Queue: Array-Based Representation Now, we need to define a Data Structure of the

    Queue. Then, we need to write the operations insert, remove, empty, and init.

    public class Queue{ // A Queue to hold 10 Characters

    private int front, rear, count; // Why 3 variables ?

    private char items[10]; // array of 10 characters

    // we just need to define the methods of the queue

    } // The new type is called Queue !

    Queue (a new type - a class )

    itemsfront rear count

    M.A. Eljinini, PhD

    Queue: Array-Based Representation Problem:

    If we keep inserting items at rear, and remove items

    from front, then we will need a mechanism for

    shifting items every time a new item is added !

    Solution:

    We shall use Circular Queues !

    C

    D E

    F

    C D E F

    front = (front + 1) % N

    rear = (rear +1 ) % N

  • M.A. Eljinini, PhD

    Queues: Operations

    We need now to write functions insert(), remove(),

    init(), and empty(), so we can access the Queue

    ONLY via these operations ! Lets start with init():

    public void init( ) // Used to initialize the queue

    {

    front = 0; // index of first item in the array

    rear = 0; // index of last item

    count = 0; // number of items in the array of the queue

    }

    And empty():

    public boolean empty( ) // return true if Queue is empty !

    {

    return (count == 0); // Zero items in Queue

    }

    M.A. Eljinini, PhD

    Queues: Operations

    Now the insert() method:

    public void insert( char r) // r is the item of type char to add

    {

    if(count != MAX) { // Check if Max is reached !

    System.out.println(Error: Queue is Full.);

    }

    else { // Now we need to add r at the rear of the queue

    // i.e. in the array items at location hold by rear

    items[ rear ] = r;

    // increment rear by 1, if MAX is reach switch to Zero !!

    rear = (rear + 1) % MAX;

    ++count; // and Finally increment Count

    }

    }

  • M.A. Eljinini, PhD

    Queues: Operations

    And the Remove() method:

    public char remove( ) // remove the first item inserted

    { // and return it the calling function

    if(count != 0) { // if no items exist, nothing can be removed

    System.out.println(Error: Queue is Empty.);

    }

    else {

    - - (count); // decrement count

    // increment Front by 1, if Zero is reach switch to MAX !!

    front = (front + 1) % MAX;

    return ( items [ front ] ); // Return the item at front

    }

    }

    M.A. Eljinini, PhD

    Queue: Linked-Based Representation Like the Linked-Based Stack, array items is

    replaced with a linked list! And, the functions need to be re-implemented to work with the linked list

    public class QNode{ // the object to hold the data

    char item; // Holds the item to be inserted

    QNode link; // referes to next node in Queue

    // do not forget to implement set and get methods

    } // It is just a node !

    We may use another class to reference front and

    rear:

    public class Queue{

    QNode front;

    QNode rear;

    } Queue;

  • Queue: Linked-Based Representation Why two classes?

    item link

    B

    Q

    item link

    NULLCA

    item link

    To Remove front item:1. Return item at front2. Move front to next node

    3. Free the first node. Do not forget to have a reference refer to this first node at first place!

    To insert item at Rear:1. Create new node of type

    QNode2. Link the new node at end3. Let rear points to the

    new node

    front rear

    The implementation of these methods are left as exercise

    M.A. Eljinini, PhD

    Applications of Stacks

    1. Use stacks to balance parentheses in infix

    notation

    Example:

    a * ( b + c ) ( ( a + b ) / c ))

    The number of left parentheses must equal to the

    number of right parentheses.

    To check for this, we may use a stack, for simple

    example, when we encounter a right parentheses;

    push it in the stack and when we encounter a left

    parentheses pop one right parentheses from the

    stack; at end the stack should be empty.

    Exercise:

    Programs in C language uses brackets { and }

    as begin and end of function, code blocks, etc.

    write a program to read a source code file in C,

    and check to see if the brackets are balanced

    (i.e. no missing or extra brackets exist).

  • M.A. Eljinini, PhD

    Applications of Stacks

    2. Use stacks in mathematical expressions:

    1. Infix Notation: (A+B)

    2. Prefix Notation: +AB

    3. Postfix Notation: AB+

    I. Transform infix to prefix:

    a. Insert parentheses, where:

    left = right = number of operations

    b. cancel all right parentheses

    c. Exchange all remaining left parentheses with

    their operations.

    Example:

    B + C * D

    ( B + ( C * D ) )

    ( B + ( C * D

    + B * C D

    M.A. Eljinini, PhD

    Applications of Stacks

    II.Transform infix to postfix:

    a. Insert parentheses, where:

    left = right = number of operations

    b. cancel all left parentheses

    c. Exchange all remaining right parentheses

    with their operations.

    Example:

    B + C * D

    ( B + ( C * D ) )

    B + C * D ) )

    B C D * +

    Question: So, when do we use the stack??

    Answer: we use a stack when we transform from prefix

    to infix, or from postfix to infix ! How?

  • M.A. Eljinini, PhD

    Applications of Stacks

    III. Transform postfix to infix:

    a. Push each operand in the stack until an

    operation is encountered.

    b. Pop two operands and wrap them around

    their operation.

    c. repeat until done.

    Example:

    B C D * + Now:* Now:+

    D

    C (C*D)

    B B (B+(C*D))

    VI. Transform Prefix to infix:

    Same as above, but we start parsing from right

    to left.

    Example: + B * C D

    1 2 3

    (Push each)

    M.A. Eljinini, PhD

    Applications of Stacks

    V. Transform postfix to prefix:

    Postfix -> infix -> prefix (Nothing new !)

    IV. Transform prefix to postfix:

    Prefix -> infix -> postfix (same)

    their operation.

    3. Use stacks to evaluate postfix:

    Example:

    10 2 / 3 + Now:/ Now:+

    2 3

    10 (10/2) 8

    Exercise:Write a Program to read a postfix from the

    keyboard, the program then should evaluate the

    expression, and output the result.

  • M.A. Eljinini, PhD

    Applications of Stacks

    4. Stacks are also used in executing recursion

    functions.

    Compilers have internal stacks that are used to

    hold all parameters and local variables of the

    recursive function at each call.

    The stack contains activation frames instead of

    simple types such as int or chars.

    Method used:

    When the executed recursive function reach the

    base, the parameters and variables of the last

    function call ( pushed last ) comes out first

    (i.e. returned first)!

    then the one before last and so on, in reverse

    order, as expected.

    M.A. Eljinini, PhD

    Applications of Queues

    1. Queues in Operating Systems:

    Acts as buffers to help synchronize interactions

    between two processes that run at different

    speeds.

    Example 1: Print Buffer (in memory)

    The CPU may produce output to be printed much

    faster than the printer can print it. The data is

    then stored in Print Buffer which is a reserved

    location in memory, that works as (FIFO) First

    jobs in, First to get printed!

    Example 2: Print Spooler (in file)

    This is used on the network (many PCs are

    connected to one printer via a server). When

    several users try to print at the same time, the

    print jobs are placed in a file on the server

    which acts like a queue First received get

    printed first.

  • M.A. Eljinini, PhD

    Applications of Queues2. Queues in Simulation experiments:

    The use of computers to model systems so we can

    study it and understand it. Serviced

    Example: Waiting Lines (FIFS)

    - Supermarket checkout

    - Bank tellers

    - Cars at gas stations

    - Plains waiting to takeoff

    - Drive-through windows of fast food outlets

    - Cars at traffic lights.

    - and many more.

    What do we simulate in real-world systems?

    - Arrival rates of clients

    - Service Time

    Why?

    To Collect statistics on the overall

    System performance.

    M.A. Eljinini, PhD

    Applications of QueuesFor example, to measure:

    - Average waiting time to obtain service

    - Variance in waiting time (i.e. how dispersed

    or spread out the waiting times are)

    - Length of the Queue

    - Throughput of the system (i.e. number of

    clients served per hour)

    Usually the simulations are run under different

    conditions. For example, varying number of tellers

    at different times at the bank!

    Benefits:

    Marketing fast Service !!

  • M.A. Eljinini, PhD

    Exercise: Stacks & QueuesThe Palindrome Problem:

    Write a program using a stack and a queue to do the

    following:

    - Read a file, one line a time (to be prepared

    in advance)

    - The program to determine if each line is a

    palindrome

    - output the line (in another file, or on the

    screen) and if palindrome or not.

    What is a palindrome?

    A line (or string) that if read left to write or

    right to left produce the same, is a palindrome.

    Examples:

    - MAM

    - 1234321

    - abababa

    - able was I ere I saw elba