Data Structures with C Using STL - PowerPoint PPT Presentation

1 / 64
About This Presentation
Title:

Data Structures with C Using STL

Description:

Radix sort. Whenever data should be processed on a first ... Efficiency of Radix Sort. The sort performs n operations for each digit or character in the keys. ... – PowerPoint PPT presentation

Number of Views:52
Avg rating:3.0/5.0
Slides: 65
Provided by: ruthu
Category:
Tags: stl | data | radix | structures | using

less

Transcript and Presenter's Notes

Title: Data Structures with C Using STL


1
Data Structures with CUsing STL
  • Chapter Eight
  • Queues and
  • Priority Queues

2
What is a Queue?
  • A queue is a sequential storage structure which
    permits access only to the two ends of the
    sequence. New elements are added at one end (the
    back), and elements are removed from the other
    end (the front).
  • A queue is a FIFO first in, first out
    structure, or FCFS first come, first serve
    structure
  • Elements are removed in the same order they were
    inserted.

3
Queue API
CLASS queue Constructors
ltqueue.hgt
queue() Create an empty queue.
CLASS queue Operations
ltqueue.hgt
bool empty() const Check whether the queue
is empty. Return true if it is empty, false
otherwise. void pop() Remove the item from
the front of the queue. Precond The queue
is not empty. Postcond Either the queue is
empty or the front of the queue is the element
that was added immediately after the
element just popped. void push(const T item)
Insert the argument item at the back of the
queue. Postcond The queue has a new item at
the back.
4
Queue API
CLASS queue Operations
ltqueue.hgt
T front() Return a reference to the value
of the item at the front of the queue.
Precond The queue is not empty. const T
front() Constant version of front. int
size() const Return the number of items in
the queue.
5
An Example
  • Queue intQ
  • int Num
  • intQ.push(10)
  • intQ.push(7)
  • intQ.push(9)
  • Num intQ.front()
  • intQ.pop()
  • intQ.push(4)
  • Num intQ.front()
  • intQ.pop()
  • intQ.push(5)
  • intQ.push(1)
  • while (!intQ..empty())
  • Num intQ.front()
  • intQ.pop()

Num
Size
0
front
rear
6
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
Size
1
front
10
rear
7
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
Size
2
front
7
10
rear
8
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
Size
3
front
7
10
9
rear
9
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
10
Size
2
front
7
9
rear
10
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
10
Size
3
front
7
9
4
rear
11
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
7
Size
2
front
9
4
rear
12
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.pus
h(5) intQ.push(1) while (!intQ..empty())
Num intQ.front() intQ.pop()
Num
7
Size
3
front
9
4
5
rear
13
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.push
(5) intQ.push(1) while (!intQ..empty()) Num
intQ.front() intQ.pop()
Num
7
Size
4
front
9
4
5
1
rear
14
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.push
(5) intQ.push(1) while (!intQ..empty()) Num
intQ.front() intQ.pop()
Num
9
Size
3
front
4
5
1
rear
15
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.push
(5) intQ.push(1) while (!intQ..empty()) Num
intQ.front() intQ.pop()
Num
4
Size
2
front
5
1
rear
16
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.push
(5) intQ.push(1) while (!intQ..empty()) Num
intQ.front() intQ.pop()
Num
5
Size
1
front
1
rear
17
An Example
Queue intQ int Num intQ.push(10) intQ.push(7)
intQ.push(9) Num intQ.front() intQ.pop() intQ
.push(4) Num intQ.front() intQ.pop() intQ.push
(5) intQ.push(1) while (!intQ..empty()) Num
intQ.front() intQ.pop()
Num
1
Size
0
front
rear
18
Applications of Queues
  • Simulation of waiting lists
  • Radix sort
  • Whenever data should be processed on a first-come
    first-served basis.

19
Radix Sort
  • Radix sort (or Bucket Sort) is based on the
    method used by card sorting machines in the early
    data processing days.
  • It sorts the keys (digit by digit or letter by
    letter). Sorting on the least significant digit
    first.
  • The sorting procedure is nothing more than
    putting each value into the bucket that
    corresponds to the digit or letter.
  • Each bucket is maintained as a queue.

20
Example of Radix sort
  • Initial Buckets Resulting
  • List 0 1 2 3 4 5
    6 7 8 9 List
  • 36
    36 31
  • 48
    48 54
  • 54
    54 24
  • 29
    29 45
  • 7
    07 36
  • 31 31
    16
  • 16
    16 07
  • 68
    68 48
  • 45
    45 68
  • 24
    24 29

21
Example of Radix sort
  • Previous Buckets Resulting
  • List 0 1 2 3 4 5
    6 7 8 9 List
  • 31 31 07
  • 54
    54 16
  • 24 24 24
  • 45 45 29
  • 36 36 31
  • 16 16
    36
  • 07 07 45
  • 48 48 48
  • 68
    68 54
  • 29 29 68

22
Efficiency of Radix Sort
  • The sort performs n operations for each digit or
    character in the keys. Thus its efficiency is
    O(mn) where m is the number of digits or
    characters in the key. As the number of digits
    or characters in the key increase the efficiency
    decreases.
  • While it may be quick, it requires enough space
    to hold all values in a single bucket, and as
    many buckets as there are possible values for a
    digit or character. This is more space than most
    other sorts discussed in this course.

23
Stable Sorting Methods
  • A sort is stable if the relative order of two
    equal values is guaranteed to be maintained.
  • For example
  • 45 23
  • 36 36
  • 59 36
  • 23 45
  • 36 59
  • 78 78

Stable Sort
24
Queue Implementation as a list
  • template lttypename Tgt
  • class queue
  • public
  • queue()
  • // constructor, create an empty queue
  • void push(const T item)
  • // insert item into the queue by inserting at
    the back of the list
  • // Postcond the queue has a new back element
    and the
  • // queue size is increased by 1
  • void pop()
  • // remove the item from the front of the queue.
  • // Precond the queue is not empty.
  • // Postcond either the queue is empty or the
    front of the // queue is the
    element that was added
  • // immediately after
    the element just popped.

25
Queue Implementation as a list-cont.
  • T front()
  • // return a reference to the element at the
    front of the queue.
  • // Precond the queue is not empty.
  • const T front() const
  • // constant version of front().
  • bool empty() conts
  • // determine whether the queue is empty.
  • int size() const
  • // return the number of elements in the queue.
  • private
  • listltTgt qList
  • // a list object maintains the queue items and
    size

26
Queue Implementation as a list-cont.
template lttypename Tgt queueltTgtqueue()
template lttypename Tgt void queueltTgtpush(const
T item) qList.push_back(item) template
lttypename Tgt void queueltTgtpop()
qList.pop_front()

27
Queue Implementation as a list-cont.
template lttypename Tgt T queueltTgtfront() retur
n qList.front() template lttypename Tgt const
T queueltTgtfront() const return
qList.front()

28
Queue Implementation as a list-cont.
  • template lttypename Tgt
  • bool queueltTgtempty()
  • return qList.empty()
  • template lttypename Tgt
  • int queueltTgtsize()
  • return qList.size()

29
Possible implementation of a queue as an array
  • We can force the front to always be 0, and when
    we dequeue and element we move all the rest of
    the elements up.
  • Advantage - we dont need a storage location for
    front.
  • Disadvantage - moving the elements up is an O(N)
    function.

30
Another Queue as Array Approach
  • We can allow the top to point to the top element
    of the queue, and rear point to the available
    place for adding an element.
  • Questions
  • What happens when there are only spaces at the
    top of the array, and no more spaces at the
    bottom of the array?

D
C
Qrear
Qfront
31
Wrap Around Solution
  • Wrap-around (circular nature of queue)
  • Solution- Assign top and rear the value zero when
    they reach the end of the array.
  • Solution - Use to move top and rear back to
    zero when they reach the end of the array.

32
Another Queue as Array Approach
  • We can allow the top to point to the top element
    of the queue, and rear point to the available
    place for adding an element.
  • Questions
  • What does this queue look like when we delete
    all of its items?

C
Qrear
Qfront
33
Another Queue as Array Approach
  • We can allow the top to point to the top element
    of the queue, and rear point to the available
    place for adding an element.
  • Questions
  • What does this queue look like if we push K and
    L?

B
C
Qrear
Qfront
34
Distinguishing Empty and Full
  • We could keep a size or count.
  • We could have a special state for empty (i.e.
    front-1)
  • we must make front -1 when we pop last item
  • we must modify front when we push first item
  • We could require that one space always be left
    unused. Then full would look different from empty.

35
Priority Queue
  • A priority queue is an ADT with the property that
    only the highest-priority element can be accessed
    at any time. When there are several elements of
    the highest priority the priority queue acts like
    a queue of those elements.
  • Every element is a key-value pair, where the key
    is the priority and the value is the data.

36
Priority Queue API
CLASS priority_queue Constructors
ltpqueue.hgt
priority_queue() Create an empty
priority_queue.
CLASS priority_queue Operations
ltpqueue.hgt
bool empty() const Check whether the
priority_queue is empty. Return true if it is
empty, false otherwise. void pop() Remove
the item with highest priority from the priority
queue. Precond The priority queue is not
empty. Postcond The priority queue has one
fewer elements. void push(const T item)
Insert the argument item into the priority
queue. Postcond The priority queue contains
a new item.
37
Priority Queue API
CLASS queue Operations
ltpqueue.hgt
T front() Return a reference to the value
of the item that has the highest priority.
Precond The priority queue is not empty. const
T front() Constant version of front. int
size() const Return the number of items in
the priority queue.
38
An implementation for priority queues
  • A priority queue can be implemented as an ordered
    array.
  • The head of the list is the element of highest
    priority.
  • New items are added after all items of the same
    priority and before all items of lower priority.

39
An implementation for priority queues
  • A priority queue can be implemented as an
    unordered array.
  • New items are added an the end of the queue.
  • The list is searched for the first element with
    the highest priority, which is deleted, by moving
    other elements below it up.

40
An implementation for priority queues
  • A heap can be used to implement a priority queue.
  • A heap is an complete tree where the root is
    larger than all other nodes in the tree, and this
    property holds for all subtrees in the tree.

41
Example of a heap
82
69
58
15
14
26
45
32
18
6
Heaps will be discussed in more detail later in
the semester
42
Time Driven Simulation
  • Simulating the arrival and departure of people at
    a bank, or printer jobs in the print queue.
  • The arrival of a particular person, or job is and
    event.
  • The departure or completion of a person's
    business or a job is an event.
  • All events occur in a sequence based on the time
    of their occurrence.

43
Time-Driven Simulation Example
  • Jobs arrive at a printer at a variable rate
    between every 2 to 10 minute. Each job may
    require between 3 and 100 pages to be printed.
    There are two printers available. One which
    prints at a rate of 5 pages per minute and the
    other prints at a rate of 7 pages per minute.
    Run a simulation of this situation for a period
    of 100 minutes, and determine how many pages each
    printer printed and what the average wait time is
    per job, and when the last job finishes printing.
    If both printers are free, a job will select the
    faster printer, otherwise the printer for a
    particular job is selected based on which printer
    will be free first.

44
Generation of job parameters
  • A random number generator is used to determine
    the arrival time and number of pages associated
    with each job.
  • When a job is generated, the arrival time for the
    next job is calculated.
  • a random number between 0 and 8 is produced an
    the next arrival time is the current time 2
    the random number.
  • The number of pages for the current job is
    determined in a similar manner

45
The simulation process
  • First jobs are generated and placed on the
    priority queue until the next job to arrive has a
    time later than the simulation end time.
  • Then the priority queue is processed with an
    event being removed from the priority queue based
    on the time stamp. When an arrival event is
    processed, it will select a printer, update the
    printer availability and place a departure event
    on the priority queue. Departure events will
    update the printer statistics and availability
    info.

46
Event ADT
  • The data for an event consists of
  • the time stamp
  • the type of event (Arrival or Departure)
  • the number of pages to be printed
  • the printer to be used
  • the wait time before the job starts printing
  • Operations include
  • Constructor
  • Methods to retrieve the various data members.
  • Methods to set the various data members
  • Method to print events to file
  • Method to compare events based on time stamp

47
Event.H
  • class event
  • private
  • time ShipTime
  • char EventType
  • int Pages
  • int PrinterUsed
  • time StartPrintingTime

48
Event.H - cont.
  • public
  • // Default constructor
  • event(time initialTimetime(), char eTypeA,
  • int pg0, int prntr1, time
    endTimetime())
  • // setInitialTime changes ShipTime of self to ST
  • // Precond ST is greater than or equal to 0.
  • // Postcond ShipTime has value of ST
  • void setInitialTime(time ST)

49
Event.H - cont.
  • // setEventType changes EventType of self to T
  • // Precond T is either A or D
  • // Postcond EventType of self is changed
    to T
  • void setEventType(char T)
  • // setPages changes Pages of self to P
  • // Precond P must be greater than 0
  • // Postcond Pages of self is changed to P
  • void setPages(int P)

50
Event.H - cont.
  • // setPrinter changes PrinterUsed of self to P
  • // Precond P is between 0 and 9 inclusive
  • // Postcond PrinterUsed of self is changed
    to P
  • void setPrinter(int P)
  • // setStartPr changes StartPrintingTime of self
    to SP
  • // Precond SP is greater than or equal to 0
  • // Postcond StartPrintingTime is set to SP
  • void setStartPr(time SP)

51
Event.H - cont.
  • // getInitTime returns ShipTime
  • time getInitTime(void)
  • // arrive returns true if EventType is A and
    false
  • // otherwise
  • bool arrive(void)
  • // depart returns true if EventType is D and
    false
  • // otherwise
  • bool depart(void)
  • // getPages returns value of Pages
  • int getPages(void)

52
Event.H - cont.
  • // getPrinter returns value of PrinterUsed
  • int getPrinter(void)
  • // getStartPr returns StartPrintingTime
  • time getStartPr(void)
  • // Print will print an event to an output file
  • // Precond The file must be open for output
  • void print(ofstream ostr)

53
Event.H - cont.
  • // Returns true if the ShipTime of self is
    greater
  • // than the ShipTime of rhs, and false
    otherwise.
  • bool operatorgt (event rhs)
  • // Returns true if the ShipTime of self is
    equal to
  • // the ShipTime of rhs, and false otherwise.
  • bool operator (event rhs)
  • // Returns true if the ShipTime of self is less
    than
  • // the ShipTime of rhs, and false otherwise.
  • bool operatorlt (event rhs)

54
Printer.H
class printer private // pages per
minute int Speed // number of pages
printed int Total pages //
time when the printer is next free time WhenFre
e
55
Printer.H - cont.
  • // Default constructor - initializes printer to
    0 pages
  • // printed and currently free, sets Speed to
  • // pgPerMinute
  • printer(int pgPerMin5)
  • // setSpeed changes Speed of self to pgPerMin
  • // Precond pgPerMin is greater than or equal
    to 0
  • // Postcond Speed is set to pgPerMin
  • void setSpeed(int pgPerMin)

56
Printer.H - cont.
  • // setWhenFree changes WhenFree of self to TWF
  • // Precond TWF is greater than or equal to 0
  • // Postcond WhenFree is set to TWF
  • void setWhenFree(time TWF)
  • // IncrTotalPages adds currPg to TotalPages
  • // Precond currPg is greater than 0
  • // Postcond TotalPages is increased by
    currPg
  • void incrTotalPages(int currPg)
  • // getSpeed returns Speed of self as pages per
    min.
  • int getSpeed(void)

57
Printer.H - cont.
// getTotalPages returns TotalPages printed for
self int getTotalPages (void) // getWhenFree
returns WhenFree for self time
getWhenFree(void)
58
Simulator.H
class simulator private // minimum time
simulation runs time simulationLength
// of printers for simulation int
numberOfPrinters // number of jobs
processed int jobCnt // total time jobs
have waited for a printer time waitCnt //
current time in simulation, records time
simulation stop time currTime // printers
used for simulation vectorltprintergt
prtlist // priority queue for
simulation priority_queue pQ // file to log
simulation actions ostream log
59
ADT Simulator Specifications
  • public
  • // Default constructor - Initializes the
    summary variables for
  • // the simulation, obtains from the user the
    parameters for the
  • // simulation, and initializes the priority
    queue with the print // jobs that come in over
    the specified time.
  • simulator(void)
  • // Simulates execution of all events in the
    priority queue.
  • // Postcond priority queue is empty, status
    variables hold
  • // result of simulation
  • void runSimulation(void)
  • // Prints the results of the simulation to
    screen.
  • // Precond runSimulation must have been
    executed.
  • void printStatistics(void)

60
Process control diagram for the printer
simulation problem
main
Simulator
Priority Queue
Printer
Random Number
ofstream
Event
Time
Time
61
Main Program for Simulation
  • include ltiostream.hgt
  • include "simulator.h"
  • include d_random.h"
  • int main()
  • simulator PrintExample
  • PrintExample.runSimulation()
  • PrintExample.printStatistics()
  • return 0

62
Simulator Constructor
  • simulatorsimulator()
  • float currTime
  • int arriveLow, arriveHigh
  • int pageLow, pageHigh
  • randomNumber rNum
  • // Get simulation parameters from user
  • . . .
  • // Initialize each printer
  • . . .
  • // Initialize statistics variables
  • . . .
  • // Open the log file
  • log.open("logfile.dat")
  • // Initialize the priority queue with arriving
    jobs.

63
Run Simulator Method
  • void simulatorrunSimulation()
  • event currEvent
  • event newEvent
  • int printerNumber
  • float JobExecutionTime
  • // Initialization
  • newEvent.setEventType('D')

64
  • while (!pQ.empty())
  • // Delete next item from pq and print it to
    the log.
  • currEvent pq.front()
  • pq.pop()
  • log ltlt "\nDelete\t"
  • currEvent.print(log)
  • if (currEvent.arrive())
  • // build Depart Event for printer job
  • . . .
  • // Insert new depart event onto the pq and
    print it to the log.
  • . . .
  • else if (currEvent.depart())
  • // Update statistics
  • . . .
  • log.close()
Write a Comment
User Comments (0)
About PowerShow.com