0% found this document useful (0 votes)
3 views

Data Structure - Queues

The document discusses queues as an abstract data type (ADT) and their implementation using arrays. It provides 3 key points: 1) A queue is a first-in, first-out (FIFO) data structure where elements can only be added to the back and removed from the front. Basic queue operations are described. 2) An array-based implementation of queues is presented, using indices to track the front and back of the queue. Issues like overflow are addressed. 3) Code snippets from Queue.h and Queue.cpp show the declaration and implementation of a Queue class including functions for enqueue, dequeue, display, and front. Private data members track the queue elements and indices.

Uploaded by

madsilveratrest
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Data Structure - Queues

The document discusses queues as an abstract data type (ADT) and their implementation using arrays. It provides 3 key points: 1) A queue is a first-in, first-out (FIFO) data structure where elements can only be added to the back and removed from the front. Basic queue operations are described. 2) An array-based implementation of queues is presented, using indices to track the front and back of the queue. Issues like overflow are addressed. 3) Code snippets from Queue.h and Queue.cpp show the declaration and implementation of a Queue class including functions for enqueue, dequeue, display, and front. Private data members track the queue elements and indices.

Uploaded by

madsilveratrest
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

Queues

Hung-Ming Chen
NCTU EE
Fall 2023

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 1
Education, Inc. All rights reserved. 0-13-140909-3
Introduction to Queues
• A queue is a waiting line – seen in daily life
– A line of people waiting for a bank teller
– A line of cars at a toll both
– "This is the captain, we're 5th in line for takeoff"
• What other kinds of queues can you think of

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 2
Education, Inc. All rights reserved. 0-13-140909-3
The Queue as an ADT
• A queue is a sequence of data elements
• In the sequence
– Items can be removed only at the front
– Items can be added only at the other end, the back
– First in, first out (FIFO)
• or FCFS
• Basic operations
– Construct a queue
– Check if empty
– Enqueue (add element to back)
– Front (retrieve value of element from front)
– Dequeue (remove element from front)
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 3
Education, Inc. All rights reserved. 0-13-140909-3
Designing and Building a Queue
Class Array-Based
• Consider an array in which to store a queue

• Note additional variables needed


– myFront, myBack
• Picture a queue
object like this
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 4
Education, Inc. All rights reserved. 0-13-140909-3
Designing and Building a Queue
Class Array-Based
• Problems
– We quickly "walk off the end" of the array
• Possible solutions
– Shift array elements
– Use a circular queue

– Note that both empty


and full queue
gives myBack == myFront
• How to solve this?
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 5
Education, Inc. All rights reserved. 0-13-140909-3
Designing and Building a Queue
Class Array-Based
• Using a static array
– QUEUE_CAPACITY specified
– Enqueue increments myBack using mod
operator, checks for full queue
– Dequeue increments myFront using mod
operator, checks for empty queue
• Note declaration of Queue class, Fig 8.2A
• View implementation, Fig. 8.2B
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 6
Education, Inc. All rights reserved. 0-13-140909-3
Queue.h void enqueue(const QueueElement & value);
/*-----------------------------------------------------------------------
/* Queue.h contains the declaration of class Queue. Add a value to a queue.
Class Invariant:
1. The queue elements (if any) are stored in consecutive positions Precondition: value is to be added to this queue.
Postcondition: value is added to back of queue provided there is space;
in myArray, beginning at position myFront.
otherwise, a queue-full message is displayed and execution is
2. 0 <= myFront, myBack < QUEUE_CAPACITY terminated.
3. Queue's size < QUEUE_CAPACITY -----------------------------------------------------------------------*/
-----------------------------------------------------------------------*/
void display(ostream & out) const;
/*-----------------------------------------------------------------------
#include <iostream>
Output the values stored in the queue.
#ifndef QUEUE
#define QUEUE Precondition: ostream out is open.
const int QUEUE_CAPACITY = 128; Postcondition: Queue's contents, from front to back, have been output
typedef int QueueElement; to out.
-----------------------------------------------------------------------*/

class Queue QueueElement front() const;


{ /*-----------------------------------------------------------------------
public: Retrieve value at front of queue (if any).
/***** Function Members *****/
Precondition: Queue is nonempty.
/***** Constructor *****/
Postcondition: Value at front of queue is returned, unless queue is
Queue(); empty; in that case, an error message is displayed and a "garbage
/*----------------------------------------------------------------------- value" is returned.
Construct a Queue object. ----------------------------------------------------------------------*/

void dequeue();
Precondition: None.
/*-----------------------------------------------------------------------
Postcondition: An empty Queue object has been constructed; myFront Remove value at front of queue (if any).
and myBack are initialized to -1 and myArray is an array with
QUEUE_CAPACITY elements of type QueueElement. Precondition: Queue is nonempty.
----------------------------------------------------------------------*/ Postcondition: Value at front of queue has been removed, unless queue
is empty; in that case, an error message is displayed and
execution is terminated.
bool empty() const; ----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
Check if queue is empty. private:
/***** Data Members *****/
int myFront, myBack;
Precondition: None.
QueueElement myArray[QUEUE_CAPACITY];
Postcondition: True is returned if the queue is empty and false is }; // end of class declaration
returned otherwise.
#endif
7
----------------------------------------------------------------------*/
Implementation //--- Definition of display()
void Queue::display(ostream & out) const
/*-- Queue.cpp----------------------------------------------------------- {
This file implements Queue member functions. for (int i = myFront; i != myBack; i = (i + 1)%QUEUE_CAPACITY)
-------------------------------------------------------------------------*/
out << myArray[i] << " ";
#include <iostream> cout << endl;
using namespace std; }

#include "Queue.h" //--- Definition of front()


//--- Definition of Queue constructor QueueElement Queue::front() const
Queue::Queue() {
: myFront(0), myBack(0) if ( !empty() )
{} return (myArray[myFront]);
else
//--- Definition of empty()
bool Queue::empty() const {
{ cerr << "*** Queue is empty -- returning garbage value ***\n";
return (myFront == myBack); QueueElement garbage;
} return garbage;
}
//--- Definition of enqueue()
void Queue::enqueue(const QueueElement & value) }
{
int newBack = (myBack + 1) % QUEUE_CAPACITY; //--- Definition of dequeue()
if (newBack != myFront) // queue isn't full void Queue::dequeue()
{ {
myArray[myBack] = value;
myBack = newBack; if ( !empty() )
} myFront = (myFront + 1) % QUEUE_CAPACITY;
else else
{ {
cerr << "*** Queue full -- can't add new value ***\n" cerr << "*** Queue is empty -- "
"Must increase value of QUEUE_CAPACITY in Queue.h\n";
exit(1); "can't remove a value ***\n";
} exit(1);
} } 8
}
Using Dynamic Array to Store
Queue Elements
• Similar problems as with list and stack
– Fixed size array can be specified too large or too
small
• Dynamic array design allows sizing of array
for multiple situations
• Results in structure as shown
– myCapacity
determined
at run time
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 9
Education, Inc. All rights reserved. 0-13-140909-3
Linked Queues
• Even with dynamic allocation of queue size
– Array size is still fixed
– Cannot be adjusted during run of program
• Could use linked list to store queue elements
– Can grow and shrink to fit the situation
– No need for upper bound (myCapacity)

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 10
Education, Inc. All rights reserved. 0-13-140909-3
Linked Queues
• Constructor initializes
myFront, myBack
• Front
– return myFront->data
• Dequeue
– Delete first node (watch for empty queue)
• Enqueue
– Insert node at end of list
• View LQueue.h declaration, Fig 8.3A
• Note definition, LQueue.cpp, Fig 8.3B
• Driver program, Fig. 8.3C
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 11
Education, Inc. All rights reserved. 0-13-140909-3
#include <iostream> LQueue.h
#ifndef LQUEUE /***** Assignment *****/
#define LQUEUE const Queue & operator= (const Queue & rightHandSide);
/*-----------------------------------------------------------------------
typedef int QueueElement; Assignment Operator

class Queue Precondition: rightHandSide is the queue to be assigned and is


{ received as a const reference parameter.
public: Postcondition: The current queue becomes a copy of rightHandSide
/***** Function Members *****/ and a reference to it is returned.
/***** Constructors *****/ -----------------------------------------------------------------------*/

Queue(); bool empty() const;


/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
Construct a Queue object. Check if queue is empty.

Precondition: None. Precondition: None.


Postcondition: An empty Queue object has been constructed. Postcondition: Returns true if queue is empty and false otherwise.
(myFront and myBack are initialized to null pointers). -----------------------------------------------------------------------*/
-----------------------------------------------------------------------*/
void enqueue(const QueueElement & value);
Queue(const Queue & original); /*-----------------------------------------------------------------------
/*----------------------------------------------------------------------- Add a value to a queue.
Copy Constructor
Precondition: value is to be added to this queue.
Precondition: original is the queue to be copied and is received
Postcondition: value is added at back of queue.
as a const reference parameter.
-----------------------------------------------------------------------*/
Postcondition: A copy of original has been constructed.
-----------------------------------------------------------------------*/

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


~Queue();
/*-----------------------------------------------------------------------
Class destructor

Precondition: None.
Postcondition: The linked list in the queue has been deallocated.
-----------------------------------------------------------------------*/
12
LQueue.h (cont’d)
void display(ostream & out) const; private:
/*-----------------------------------------------------------------------
Display values stored in the queue.
/*** Node class ***/
class Node
Precondition: ostream out is open. {
Postcondition: Queue's contents, from front to back, have been
public:
output to out.
-----------------------------------------------------------------------*/ QueueElement data;
Node * next;
QueueElement front() const;
//--- Node constructor
/*-----------------------------------------------------------------------
Retrieve value at front of queue (if any). Node(QueueElement value, Node * link = 0)
/*-------------------------------------------------------------------
Precondition: Queue is nonempty. Precondition: value and link are received
Postcondition: Value at front of queue is returned, unless the
queue is empty; in that case, an error message is displayed Postcondition: A Node has been constructed with value in its
and a "garbage value" is returned. data part and its next part set to link (default 0).
-----------------------------------------------------------------------*/ ------------------------------------------------------------------*/
void dequeue(); { data = value; next = link; }
/*-----------------------------------------------------------------------
Remove value at front of queue (if any). };
Precondition: Queue is nonempty.
Postcondition: Value at front of queue has been removed, unless typedef Node * NodePointer;
queue is empty; in that case, an error message is displayed
and execution allowed to proceed.
/***** Data Members *****/
-----------------------------------------------------------------------*/
NodePointer myFront, // pointer to front of queue
myBack; // pointer to back of queue

}; // end of class declaration

13
Implementation
//--- Definition of Queue destructor
Queue::~Queue()
{
// Set pointer to run through the queue
/*--- LQueue.cpp ---------------------------------------------------------- Queue::NodePointer prev = myFront,
This file implements LQueue member functions. ptr;
-------------------------------------------------------------------------*/
while (prev != 0)
{
#include <new>
using namespace std; ptr = prev->next;
delete prev;
#include "LQueue.h" prev = ptr;
}
//--- Definition of Queue constructor }
Queue::Queue() //--- Definition of assignment operator
: myFront(0), myBack(0) const Queue & Queue::operator=(const Queue & rightHandSide)
{} {
if (this != &rightHandSide) // check that not q = q
//--- Definition of Queue copy constructor
{
Queue::Queue(const Queue & original)
this->~Queue(); // destroy current linked list
{
myFront = myBack = 0; if (rightHandSide.empty()) // empty queue
if (!original.empty()) myFront = myBack = 0;
{ else
// Copy first node { // copy rightHandSide's list
myFront = myBack = new Queue::Node(original.front()); // Copy first node
myFront = myBack = new Queue::Node(rightHandSide.front());
// Set pointer to run through original's linked list
Queue::NodePointer origPtr = original.myFront->next; // Set pointer to run through rightHandSide's linked list
while (origPtr != 0) Queue::NodePointer rhsPtr = rightHandSide.myFront->next;
{
while (rhsPtr != 0)
myBack->next = new Queue::Node(origPtr->data);
{
myBack = myBack->next;
origPtr = origPtr->next; myBack->next = new Queue::Node(rhsPtr->data);
} myBack = myBack->next;
} rhsPtr = rhsPtr->next;
} }
}
}
return *this; 14
}
Implementation //--- Definition of front()
//--- Definition of empty()
QueueElement Queue::front() const
bool Queue::empty() const
{
{
return (myFront == 0); if (!empty())
} return (myFront->data);
else
//--- Definition of enqueue() {
void Queue::enqueue(const QueueElement & value) cerr << "*** Queue is empty "
{ " -- returning garbage ***\n";
Queue::NodePointer newptr = new Queue::Node(value); QueueElement * temp = new(QueueElement);
if (empty()) QueueElement garbage = *temp; // "Garbage" value
myFront = myBack = newptr;
delete temp;
else
return garbage;
{
myBack->next = newptr; }
myBack = newptr; }
}
} //--- Definition of dequeue()
void Queue::dequeue()
//--- Definition of display() {
void Queue::display(ostream & out) const if (!empty())
{ {
Queue::NodePointer ptr;
Queue::NodePointer ptr = myFront;
for (ptr = myFront; ptr != 0; ptr = ptr->next)
myFront = myFront->next;
out << ptr->data << " ";
out << endl; delete ptr;
if (myFront == 0) // queue is now empty
} myBack = 0;
}
else
cerr << "*** Queue is empty -- can't remove a value ***\n";
}
15
Driver
#include <iostream>
using namespace std;
cout << "Queue q2 empty? " << q2.empty() << endl;
#include "LQueue.h"
cout << "Front value in q2: " << q2.front() << endl;
void print(Queue q)
{ q.display(cout); } while (!q2.empty())
{
int main() cout << "Remove front -- Queue contents: ";
{ q2.dequeue();
Queue q1; q2.display(cout);
cout << "Queue created. Empty? " << boolalpha }
<< q1.empty() << endl; cout << "Queue q2 empty? " << q2.empty() << endl;
cout << "Front value in q2?" << endl << q2.front() << endl;
cout << "How many elements to add to the queue? "; cout << "Trying to remove front of q2: " << endl;
int numItems; q2.dequeue();
cin >> numItems; }
for (int i = 1; i <= numItems; i++)
q1.enqueue(100*i);

cout << "Contents of queue q1 (via print):\n";


print(q1); cout << endl;

Queue q2;
q2 = q1;
cout << "Contents of queue q2 after q2 = q1 (via print):\n";
print(q2); cout << endl;
16
Execution Trace Sample

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 17
Education, Inc. All rights reserved. 0-13-140909-3
Execution Trace Sample

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 18
Education, Inc. All rights reserved. 0-13-140909-3
Circular Linked List
• Possible to treat the linked list as circular

– Last node points back to first node


– Alternatively keep pointer to last node rather
than first node; this variation is especially useful
when it is necessary to access repeatedly at the
ends of the list
• last->next points to
the first node
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 19
Education, Inc. All rights reserved. 0-13-140909-3
Application of Queues:
Buffers and Scheduling
• Important use of queues is I/O buffering
– Use buffers in main memory to improve program
execution
– Buffer arranged
in FIFO structure
– A queue-empty condition
means the input buffer is
empty and program execution is suspended
while OS loads more data into the buffer
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 20
Education, Inc. All rights reserved. 0-13-140909-3
Application of Queues:
Buffers and Scheduling
• Sometimes insertions, deletions must be
made from both ends
– Consider a scrolling
window on the screen
• This requires a double
ended queue
– Called a deque (pronounced "deck")

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 21
Education, Inc. All rights reserved. 0-13-140909-3
Application of Queues:
Buffers and Scheduling
• Consider a keyboard buffer (interactive
input)
– Acts as a queue
– But elements may be
removed from the back of
the queue with
backspace key
• A printer spool (simultaneous peripheral
operation on-line) is a queue of print jobs
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 22
Education, Inc. All rights reserved. 0-13-140909-3
Application of Queues:
Buffers and Scheduling
• Queues used to
schedule tasks
within an operating
system

• Job moves from disk to ready queue


– Will be moved to suspended queue when waiting
for I/O
– After I/O completed, it will be moved back to
ready queue
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 23
Education, Inc. All rights reserved. 0-13-140909-3
Application of Queues:
Buffers and Scheduling
• Ready queue may actually
be a priority queue … job may get to "cut the
line" based on its priority

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 24
Education, Inc. All rights reserved. 0-13-140909-3
Application 2: Information
Center/Customer Service Simulation
• Most waiting lines (queues) are dynamic
– Their lengths grow and shrink over time
• Simulation models this dynamic process
– Enables study of the behavior of the process
– Modeled with one or more equations
• Queue behavior involves randomness
– We will use pseudorandom number generator

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 25
Education, Inc. All rights reserved. 0-13-140909-3
Problem Analysis and Specification
• Consider an information center
– Calls arrive at random intervals
– Placed in queue of incoming calls
– When agent becomes available, services call at
front of queue
• We will simulate receipt of "calls" for some
number of "minutes"
– we keep track of calls in the queue

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 26
Education, Inc. All rights reserved. 0-13-140909-3
Problem Analysis and Specification
• Input to the simulation program
– Time limit
– Arrival rate of calls
– Distribution of service times
• myServicePercent[0] = percent of calls serviced in 1
min or less
• Desired output
– Number of calls processed
– Average waiting time per call
• Note declaration of Simulation class, Fig. 8-4
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 27
Education, Inc. All rights reserved. 0-13-140909-3
#include <iostream>
Simulation Class
// istream, ostream, >>, <<
#include <ctime> // time() /***** Output *****/
void display(ostream & out);
#ifndef SIMULATION /*----------------------------------------------------------------------
#define SIMULATION Display results of the simulation.
Precondition: ostream out is open.
#include "Timer.h" Postcondition: Total number of calls and the average waiting time
#include "Call.h" for calls have been output to out.
#include "LQueue.h" // Queue with elements of type Call -----------------------------------------------------------------------*/

const int NUM_CATEGORIES = 5; /***** Call processing *****/


class Simulation void service(int & busyTimeRemaining);
{ /*----------------------------------------------------------------------
public:
Service the current call (if any).
/***** Function Members *****/
Precondition: None
/***** Constructor *****/
Postcondition: busyTimeRemaining has been decremented by one if a call
Simulation();
was being serviced; otherwise, if there were incoming calls, a
/*-----------------------------------------------------------------------
call has been removed from myIncomingCalls, its service time
Construct a Simulation object.
assigned to busyTimeRemaining, and its waiting time in the queue
Precondition: None
Postcondition: Input data members have been initialized with values added to myTotalWaitingTime.
entered by the user; output data members have been initialized -----------------------------------------------------------------------*/
to 0; and random number generator has been initialized.
-----------------------------------------------------------------------*/

/***** Running the simulation *****/


void run();
/*-----------------------------------------------------------------------
Run the simulation.
Precondition: None.
Postcondition: Simulation of phone service has been completed and
performance statistics output.
-----------------------------------------------------------------------*/
28
Simulation Class (cont’d)
void checkForNewCall();
/*----------------------------------------------------------------------
Check if a new call has arrived and if so, add it to the
queue of incoming calls.
Precondition: None.
Postcondition: myIncomingCalls has been updated.
-----------------------------------------------------------------------*/
private:
/***** Data Members *****/
//-- Inputs
int myLengthOfSimulation;
double myArrivalRate;
int myServicePercent[NUM_CATEGORIES];

//-- Outputs
int myCallsReceived;
double myTotalWaitingTime;

//-- Countdown Timer


Timer myTimer;

//-- Queue of calls waiting for service


Queue myIncomingCalls;

}; // end of class declaration

#endif 29
Problem Analysis and Specification
• Constructor
– Initialize input data members
– myTimer, myIncomingCalls initialized by their
constructors
• The run() method
– Starts and manages simulation
• The checkForNewCall() method
– Random number generated, compared to myArrivalRate
– If new call has arrived, create new Call object, place in
queue

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 30
Education, Inc. All rights reserved. 0-13-140909-3
Problem Analysis and Specification
• The service() method
– Checks time remaining for current call
– When done, retrieves and starts up next call from front of
queue
• The display() method
– Report generated at end of simulation
• View definition of function members
Fig. 8-5A
• Note driver program for simulation, Fig. 8-5B
• Reference: the Timer class and Call class used in
the Simulation class
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 31
Education, Inc. All rights reserved. 0-13-140909-3
Implementation
/*-- Simulation.cpp --------------------------------------------------------
Definitions of function members of class Simulation.
-------------------------------------------------------------------------*/
//--- Definition of run()
#include <iostream> // istream, ostream, >>, <<
void Simulation::run()
#include <cstdlib> // rand(), srand()
{
#include <ctime> // time()
using namespace std;
// Begin the simulation
int busyTimeRemaining = 0;
#include "Simulation.h" while (myTimer.timeRemaining() > 0)
{
//--- Definition of constructor service(busyTimeRemaining);
Simulation::Simulation() checkForNewCall();
{ myTimer.tick();
//-- Initialize output statistics }
myCallsReceived = 0; cout << "\nNot accepting more calls -- service those waiting\n";
myTotalWaitingTime = 0;
//-- Get simulation parameters
// Service any remaining calls in incomingCalls queue
cout << "Enter arrival rate (calls per hour): ";
while (!myIncomingCalls.empty())
int callsPerHour;
{
cin >> callsPerHour;
myArrivalRate = callsPerHour / 60.0; // convert to calls per minute
service(busyTimeRemaining);
myTimer.tick();
cout << "Enter percent of calls serviced in\n"; }
int percent,
sum = 0; // Output the results
for (int i = 0; i < NUM_CATEGORIES - 1; i++) display(cout);
{ }
cout << " <= " << i + 1 << " min. "; cin >> percent;
sum += percent; //--- Definition of display()
myServicePercent[i] = sum; void Simulation::display(ostream & out)
}
{
myServicePercent[NUM_CATEGORIES - 1] = 100;
out << "\nNumber of calls processed: " << myCallsReceived
cout << "Enter # of minutes to run simulation: ";
<< "\nAve. waiting time per call: "
cin >> myLengthOfSimulation;
<< myTotalWaitingTime / myCallsReceived
<< " minutes" << endl;
// Set the countdown timer }
myTimer.set(myLengthOfSimulation);

//-- Initialize random number generator


long seed = long(time(0)); // seed for random number generator
srand(seed);
32
}
Implementation (cont’d)
//--- Definition of service() //--- Definition of checkForNewCall()
void Simulation::service(int & busyTimeRemaining) void Simulation::checkForNewCall()
{ {
if (busyTimeRemaining > 0) // servicing a call int x = rand() % 100;
busyTimeRemaining--; // service it for another minute
else if (x < 100 * myArrivalRate)
if (!myIncomingCalls.empty()) // calls are waiting -- get one {
{ // A new call has arrived. Generate a random service time for it
Call nextCall = myIncomingCalls.front(); int r = rand() % 100;
myIncomingCalls.dequeue();
busyTimeRemaining = nextCall.getServiceTime(); int serviceTime = 0;
while (r > myServicePercent[serviceTime])
// Update total waiting time serviceTime++;
myTotalWaitingTime +=
nextCall.getArrivalTime() - myTimer.timeRemaining(); // Construct a new call and add it to queue of incoming calls
} Call newCall(myTimer, serviceTime + 1);
} myIncomingCalls.enqueue(newCall);
myCallsReceived++;
}
}

33
Call.h
/*-- Call.h ---------------------------------------------------
int getArrivalTime() const;
/*----------------------------------------------------------
This header file defines a class Call that models phone calls. Accessor function for arrival time.
Basic operations: Precondition: None
constructors: construct a Call object Postcondition: Value of myTimeOfArrival was returned.
getArrivalTime(): accessor to get time call arrived -----------------------------------------------------------*/
getServiceTime(): get time needed to service the call
display(): display information about the call int getServiceTime() const;
<<: output operator for a Call object /*----------------------------------------------------------
--------------------------------------------------------------*/
Accessor function for service time.
#include <iostream>
Precondition: None
#include "Timer.h"
Postcondition: Value of myServiceTime was returned.
-----------------------------------------------------------*/
#ifndef CALL
#define CALL
void display(ostream & out) const;
class Call
/*----------------------------------------------------------
{ Display call
public: Precondition: ostream out is a reference parameter
/***** Function Members *****/ Postcondition: Call has been output to out.
/***** Constructor *****/ -----------------------------------------------------------*/
Call();
/*---------------------------------------------------------- private:
Construct a Call object (default). /***** Data Members *****/
Precondition: None int myTimeOfArrival;
Postcondition: All data members are initialized to 0. int myServiceTime;
-----------------------------------------------------------*/ }; // end of Timer class declaration
Call(const Timer & t, int serviceTime);
/*----------------------------------------------------------
Construct a Call object (explicit-value). //--- Prototype for output operator
Precondition: Countdown timer t is received ostream & operator<<(ostream & out, const Call & aCall);
Postcondition: myTimeOfArrival has been set to time left
on Timer t and myServiceTime to serviceTime.
#endif 34
-----------------------------------------------------------*/
Call Implementation
/*-- Call.cpp -------------------------------------------------- //--- Definition of getArrivalTime()
Contains definitions of the basic Call operations. int Call::getArrivalTime() const
--------------------------------------------------------------*/ {
return myTimeOfArrival;
#include <iostream> }
#include <cassert>
using namespace std; //--- Definition of getServiceTime()
int Call::getServiceTime() const
#include "Call.h" {
return myServiceTime;
}
//--- Definition of Default Constructor
Call::Call() //--- Definition of display()
{ void Call::display(ostream & out) const
myTimeOfArrival = myServiceTime = 0; {
} out << "Arrival Time: " << myTimeOfArrival << endl
<< "Service Time: " << myServiceTime << endl;
//--- Definition of Explicit-Value Constructor }
Call::Call(const Timer & t, int serviceTime)
{ //-- Definition of output operator
// record call's time of arrival ostream & operator<<(ostream & out, const Call & aCall)
myTimeOfArrival = t.timeRemaining(); {
aCall.display(out);
// set its service time return out;
myServiceTime = serviceTime; }
}

35
Driver
/*-------------------------------------------------------------
Driver program for simulation of information/reservation
center that services telephone calls
--------------------------------------------------------------*/

using namespace std;

#include "Simulation.h"

int main()
{
Simulation sim;
sim.run();

return 0;
}

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 36
Education, Inc. All rights reserved. 0-13-140909-3
Execution Trace
Enter arrival rate (calls per hour): 15
Enter percent of calls serviced in
<= 1 min. 50
<= 2 min. 25
<= 3 min. 15
<= 4 min. 7
Enter # of minutes to run simulation: 500
Not accepting more calls – service those waiting

Number of calls processed: 112


Ave. waiting time per call: 2.57143 minutes

Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 37
Education, Inc. All rights reserved. 0-13-140909-3
Application 3: Image-Component Labeling

Data Structures, Algorithms, and Applications in C++, 2nd ed, SAHNI 38


How to Label the Components?
• The components are determined by scanning
the pixels by rows and within rows by columns
• When an unlabeled component pixel is reached,
we will assign a component identifier/label
– This pixel forms the seed of a new component
• We determine the remaining pixels in the
component by identifying and labeling all
component pixels that are adjacent to the seed
– The idea is to check neighboring pixel positions,
saving those in a queue, processing until the queue
is empty

Data Structures, Algorithms, and Applications in C++, 2nd ed, SAHNI 39


Component Labeling: C++ Implementation

Data Structures, Algorithms, and Applications in C++, 2nd ed, SAHNI 40


Component Labeling (cont’d)

1. Stack ok?
2. Complexity?

41

You might also like