Docstoc

lec-12_ 13 dsa_uaar

Document Sample
lec-12_ 13 dsa_uaar Powered By Docstoc
					Queues


 Nawazish Naveed
Queues

“A Queue is a special kind of list, where
   items are inserted at one end (the rear)
   And deleted at the other end (the front)”
 Other Name:
  First In First Out (FIFO)

Difference from Stack:
  Insertion go at the end of the list, rather
  than the beginning of the list.
Common Operations on Queues
(Queue ADT)
1.   MAKENULL(Q): Makes Queue Q be an empty list.
2.   FRONT(Q): Returns the first element on Queue Q.
3.   ENQUEUE(x,Q): Inserts element x at the end of
     Queue Q.
4.   DEQUEUE(Q): Deletes the first element of Q.
5.   EMPTY(Q): Returns true if and only if Q is an empty
     queue.
Example:
Line of customers in a bank
Applications of Queues
   Operating system
     multi-user/multitaskingenvironments, where
      several users or task may be requesting the
      same resource simultaneously.
   Communication Software
     queues   to hold information received over
      networks and dial up connections.
      (Information can be transmitted faster than it
      can be processed, so is placed in a queue
      waiting to be processed)
   Some other?
Implementation
   Static
     Queue  is implemented by an array, and size
      of queue remains fix
   Dynamic
    A   queue can be implemented as a linked
      list, and expand or shrink with each enqueue
      or dequeue operation.
A pointer Implementation of
Queues
Keep two pointers:
 FRONT: A pointer to the first element of the
  queue.
 REAR: A pointer to the last element of the
  queue.
Front       x            y           z     .
Rear
A pointer Implementation of
Queues
MAKENULL(Q)

                NULL
    Q.front

    Q.Rear


ENQUEUE(x,Q)

                        x     .
    Q.front

    Q.Rear
A pointer Implementation of
Queues
ENQUEUE(y,Q)

                      x       y   .
    Q.front
    Q.Rear

DEQUEUE(Q)

                              y   .
    Q.front
    Q.Rear
              A class for Dynamic Queue implementation
class DynIntQueue
{
private:
       struct QueueNode
       {
               int value;
               QueueNode *next;
       };

          QueueNode *front;
          QueueNode *rear;
          int numItems;
public:
          DynIntQueue(void);
          ~DynIntQueue(void);
          void enqueue(int);
          int dequeue(void);
          bool isEmpty(void);
          void makeNull(void);
};
                             Implemenaton

//************************
// Constructor           *
//************************

DynIntQueue::DynIntQueue(void)
{
        front = NULL;
        rear = NULL;
        numItems = 0;
}

//************************
// Destructor            *
//************************

DynIntQueue::~DynIntQueue(void)
{
        makeNull();
}
//********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue.                 *
//********************************************

void DynIntQueue::enqueue(int num)
{
       QueueNode *newNode;

       newNode = new QueueNode;
       newNode->value = num;
       newNode->next = NULL;
       if (isEmpty())
       {
               front = newNode;
               rear = newNode;
       }
       else
       {
               rear->next = newNode;
               rear = newNode;
       }
       numItems++;
}
//**********************************************
// Function dequeue removes the value at the   *
// front of the queue, and copies it into num. *
//**********************************************

int DynIntQueue::dequeue(void)
{
       QueueNode *temp;
       int num;
       if (isEmpty())
              cout << "The queue is empty.\n";
       else
       {
              num = front->value;
              temp = front->next;
              delete front;
              front = temp;
              numItems--;
       }
       return num;

}
//*********************************************
// Function isEmpty returns true if the queue *
// is empty, and false otherwise.             *
//*********************************************

bool DynIntQueue::isEmpty(void)
{
       if (numItems)
              return false;
       else
              return true;
}
//********************************************
// Function makeNull dequeues all the elements   *
// in the queue.                             *
//********************************************

void DynIntQueue::makeNull(void)
{
       while(!isEmpty())
              dequeue();
}
                            Program
// This program demonstrates the DynIntQeue class
void main(void)
{
       DynIntQueue iQueue;

      cout << "Enqueuing 5 items...\n";
      // Enqueue 5 items.
      for (int x = 0; x < 5; x++)
             iQueue.enqueue(x);

      // Deqeue and retrieve all items in the queue
      cout << "The values in the queue were:\n";
      while (!iQueue.isEmpty())
      {
             int value;
              value =iQueue.dequeue();
             cout << value << endl;
      }
}
Program Ouput
Enqueuing 5 items...
The values in the queue were:
0
1
2
3
4
       Array Implementation
                   When queue is empty both front and rear are set to -1
                   While enqueueing increment rear by 1, and while dequeueing
                   increment front by 1
                   When there is only one value in the Queue, both rear and front
                   have same index
Front
             First Element
                              Can we implement Queue by using only one
             Second
             Element
                .
                              index variable Front or Rear??
               .              YES, by moving elements of array to neighboring
                              locations like we did in STACK but this is in-
                              efficient
Rear
             Last Element     Why it is inefficient?
              maxlength
Array Implementation
  5    4     6     7     8     7     6
  0    1     2     3      4     5     6    7     8
      Front=0
      Rear=6

                         8     7     6
  0    1     2     3      4     5     6    7     8
      Front=4
      Rear=6

                               7     6     12    67
  0    1     2   3     4      5     6     7    8
      Front=5
               How can we insert more elements? Rear index can
      Rear=8
                 not move beyond the last element….
Solution: Using circular queue
 Allow rear to wrap around the array.
  if(rear == queueSize-1)
      rear = 0;
  else
      rear++;
 Or use module arithmetic
  rear = (rear + 1) % queueSize;
                              7      6     12    67
0     1     2    3      4      5     6     7     8
     Front=5
     Rear=8

Enqueue 39      Rear=(Rear+1) mod Queue Size = (8+1) mod 9 = 0
39                            7      6     12    67
0     1     2    3      4      5     6     7     8
     Front=5
     Rear=0
How to determine empty and full
Queues?
 It is some tricky
 Number of approaches
    A  counter indicating number of values in the
      queue can be used (We will use this
      approach)
     We will see another approach as well at the
      end
 Implementation
class IntQueue
{
private:
        int *queueArray;
        int queueSize;
        int front;
        int rear;
        int numItems;
public:
        IntQueue(int);
        ~IntQueue(void);
        void enqueue(int);
        int dequeue(void);
        bool isEmpty(void);
        bool isFull(void);
        void clear(void);
};
Note, the member function clear, which clears the queue by resetting the front
and rear indices, and setting the numItems to 0.
IntQueue::IntQueue(int s) //constructor
{
    queueArray = new int[s];
    queueSize = s;
    front = -1;
    rear = -1;
    numItems = 0;
}


IntQueue::~IntQueue(void) //destructor
{
     delete [] queueArray;
}
//********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue.                 *
//********************************************

void IntQueue::enqueue(int num)
{
      if (isFull())
            cout << "The queue is full.\n";
      else
      {
            // Calculate the new rear position
            rear = (rear + 1) % queueSize;
            // Insert new item
            queueArray[rear] = num;
            // Update item count
            numItems++;
      }
}
//*********************************************
// Function dequeue removes the value at the *
// front of the queue, and copies t into num. *
//*********************************************

int IntQueue::dequeue(void)
{
       if (isEmpty())
              cout << "The queue is empty.\n";
       else
       {
               // Retrieve the front item
              int num = queueArray[front];
              // Move front
              front = (front + 1) % queueSize;
              // Update item count
              numItems--;
       }
       return num;
}
//*********************************************
// Function isEmpty returns true if the queue *
// is empty, and false otherwise.             *
//*********************************************

bool IntQueue::isEmpty(void)
{
       if (numItems)
              return false;
       else
              return true;
}
//********************************************
// Function isFull returns true if the queue *
// is full, and false otherwise.             *
//********************************************

bool IntQueue::isFull(void)
{
       if (numItems < queueSize)
              return false;
       else
              return true;
}
//*******************************************
// Function clear resets the front and rear *
// indices, and sets numItems to 0.         *
//*******************************************

void IntQueue::clear(void)
{
       front = - 1;
       rear = - 1;
       numItems = 0;
}
//Program demonstrating the IntQueue class
void main(void)
{
       IntQueue iQueue(5);

       cout << "Enqueuing 5 items...\n";
       // Enqueue 5 items.
       for (int x = 0; x < 5; x++)
               iQueue.enqueue(x);

       // Attempt to enqueue a 6th item.
       cout << "Now attempting to enqueue again...\n";
       iQueue.enqueue(5);
       // Deqeue and retrieve all items in the queue
       cout << "The values in the queue were:\n";
       while (!iQueue.isEmpty())
       {
               int value;
               iQueue.dequeue(value);
               cout << value << endl;
       }
}
Program Output
Enqueuing 5 items...
Now attempting to enqueue again...
The queue is full.
The values in the queue were:
0
1
2
3
4
Another implementation of Queues
using Arrays
class CQueue
{
   int Data*,QueueSize,Front,Rear;
public:
   CQueue(int size);
   ~CQueue(int size);
   bool IsFull();
   bool IsEmpty();
   void Enqueue(int num);
   int Dequeue();
   void MakeNull;
};
CQueue::CQueue(int size)
{
    Front=Rear=-1;
    Data=new int[size];
}
void CQueue ::Enqueue(int num);
{
    if (IsFull()) { cout<<“Overflow” return; }
    if (IsEmpty() Rear=Front=0;
    else Rear=(Rear+1) % QueueSize;
    Data[Rear]=num;
}
int CQueue ::Dequeue(int num);
  {
      if (IsEmpty()) { cout<<“Underflow”; return; }
      int ReturnValue=Data[Front];
      if (Front==Rear) //only one element in the queue
              Front=Rear=-1;
      else
              Front=(Front+1) % QueueSize;
      return ReturnValue;
  }
bool CQueue::IsEmpty()
{
  if (Front==-1) return true;
  else return false;
}
bool CQueue::IsFull()
{
  If (((Rear+1)%QueueSize)==Front)
        return true;
  else return false;
}
         First In First Out


                                      D   rear
                            C   rear C          D   rear
                  B   rear B          B         C
          rear        front A                       front
     A            A             front A   front B
          front


Difference from Stack:
  Insertion go at the end of the list, rather than
  the beginning of the list.
36
Applications of Queues
    Operating system
      multi-user/multitaskingenvironments, where
       several users or task may be requesting the
       same resource simultaneously.
    Communication Software
      queues   to hold information received over
       networks and dial up connections.
       (Information can be transmitted faster than it
       can be processed, so is placed in a queue
       waiting to be processed)
    Some other?

37
 Static
 Queue   is implemented by an array, and size of
   queue remains fix


 Dynamic
 A  queue can be implemented as a linked list,
   and expand or shrink with each enqueue or
   dequeue operation.



  38
                                        38
1.    MAKENULL(Q): Makes Queue Q be an empty list.
2.    FRONT(Q): Returns the first element on Queue Q.
3.    ENQUEUE(x,Q): Inserts element x at the end of Queue Q.
4.    DEQUEUE(Q): Deletes the first element of Q.
5.    EMPTY(Q): Returns true if and only if Q is an empty
      queue.


     Example:
     Line of customers in a bank
     39
                                                  39
40
Implementation
    Static
      Queue  is implemented by an array, and size
       of queue remains fix
    Dynamic
     A   queue can be implemented as a linked
       list, and it can expand or shrink with each
       enqueue or dequeue operation.


41
    Array-based Queue Implementation
      As with the array-based stack implementation, the
        array is of fixed size
                A queue of maximum N elements
            Slightly more complicated
                Need to maintain track of both front and rear


Implementation 1




Implementation 2




    42
       Array Implementation     When queue is empty both front and rear are set to -1

                                While enqueueing increment rear by 1, and while
                                 dequeueing increment front by 1

                                When there is only one value in the Queue, both rear
                                 and front have same index




Front                                  Can we implement Queue by using only one
             First Element              index variable Front or Rear??
             Second                    YES, by moving elements of array to
             Element
                .                       neighboring locations like we did in STACK but
                                        this is in-efficient
               .

                                       Why it is inefficient?

Rear
             Last Element

              maxlength



       43
     Implementation 1: createQ, isEmptyQ,
                   isFullQ

 Queue createQ(max_queue_size) {
 # define MAX_QUEUE_SIZE 100
 // Maximum queue size
 int queue[MAX_QUEUE_SIZE];
 int rear = -1;
 int front = -1;
 Boolean isEmpty(queue) ::= front == rear
 Boolean isFullQ(queue) ::= rear ==(n-1)



44
           Implementation 1: enqueue
void enqueue(int rear, int item)
{
//add an item to the queue
    if (rear == MAX_QUEUE_SIZE)
  {
       queue_full( );
       return;
   }
   queue [++rear] = item;
}



45
            Implementation 1: dequeue

     int dequeue(int front, int rear)
     {
     // remove element at the front of the queue
         if ( *front == rear)
             return queue_empty( );
         return queue [++ front];
     }




46
Circular Queues and
Implementation with Array
Array Implementation
     5    4    6      7     8     7     6
     0    1     2     3      4     5     6    7     8
         Front=0
         Rear=6

                            8     7     6
     0    1     2     3      4     5     6    7     8
         Front=4
         Rear=6
                                  7     6     12    67
     0    1     2     3      4     5     6    7     8
         Front=5
         Rear=8
                    How can we insert more elements? Rear index can
                    not move beyond the last element….

48
Solution: Using circular queue
 Allow rear to wrap around the array.
  if(rear == queueSize-1)
      rear = 0;
  else
      rear++;
 Or use modulo arithmetic
  rear = (rear + 1) % queueSize;


49
Enqueing in a Circular Queue

                                   7      6     12    67
     0     1     2    3      4      5     6     7     8
          Front=5
          Rear=8

     Enqueue 39      Rear=(Rear+1) mod Queue Size = (8+1) mod 9 = 0
     39                            7      6     12    67
     0     1     2    3      4      5     6     7     8
          Front=5
          Rear=0



50
     Implementation 2: Wrapped Configuration

EMPTY QUEUE
            [2]                [3]            [2]                 [3]
                                                    J2       J3

      [1]                            [4]   [1] J1                       [4]


                  [0]      [5]                      [0]        [5]


                   front = 0                             front = 0
                   rear = 0                              rear = 3

       Can be seen as a circular queue

51
  How to determine empty and full
  Queues?     FULL QUEUE  FULL QUEUE
Leave one empty
                         [2]                       [3]     [2]                          [3]
space when queue
                                J2          J3                     J8        J9
is full
Why?               [1]                                 [4][1] J7                              [4]
                           J1                     J4

                                        J5                          J6       J5

                               [0]          [5]                    [0]            [5]

                                 front =0                                front =4
                                 rear = 5                                rear =3
 How to test when queue is empty?
 How to test when queue is full?
  52
How to determine empty and full
Queues?
    Number of approaches
     A counter indicating number of values in the
      queue can be used (We will use this
      approach)

      Comparing   the Rear and the Front of the
      Queue


53

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:3
posted:2/25/2012
language:English
pages:53