Project 8: Priority Queues

Generic implementations of priority queue

Educational Objectives: After completing this assignment, the student should be able to accomplish the following:

Pre-requisite Knowledge Required: Be sure that you have mastered the material in these chapters before beginning the assignment:
Iterators, Generic Algorithms, Introduction to Trees, and Binary Heaps.

Operational Objectives: Design and implement six (6) distinct implementations of the Priority Queue template PriorityQueue<T,P> based on List<T>, MOList<T,P>, Vector<T> (2), MOVector<T,P>, and Deque<T>. Use namespaces pq1, pq2, ... , pq6 to scope the six variations.

Deliverables: Two files pq.h and log.txt

Background:

A priority queue stores elements of typename T with a priority determined by an object of a predicate class P. The operations are syntactically queue-like but have associative semantics (rather than positional semantics, as in an ordinary queue). The operations for a priority queue PQ<T,P> and informal descriptions of them are as follows:

as well as default constructor, destructor, copy constructor, and assignment operator (i.e., we need priority queue to be a proper type). We will also use the following additional operations:

These last operations are useful in development and performace testing. We could, for example, drop in a "spy" version of order and use GetPredicate to obtain counts of the number of calls, obtaining runtime data on the implementation. Dump gives a snapshot of the underlying container, useful in development and testing.

Priority queues are used in several important applications, including:

Priority queues are traditionally built as adaptations of other data structures using special algorithms. The most sophisticated of these are discussed in the chapter Binary Heaps. However, us usual, "most sophisticated" does not always translate as "best". "Best" is usually determined by client programmers based on the client needs. (Compare g_insertion_sort() with g_heap_sort() for example.)

In this assignment you will build priority queues using (1) one of our familiar Containers Vector<T>, Deque<T>, List<T>, MOVector<T,P>, MOList<T,P> as the data storage facility and (2) an appropriate algorithm for the search mechanism. In the case of heap-based priority queue (case 6) two generic algorithms will be required.

Procedural Requirements

  1. The official development/testing/assessment environment is specified in the Course Organizer.

  2. Be sure start and maintain your log.txt.

  3. After creating your log.txt, begin by copying all of the files from LIB/proj8 into your project directory.

  4. Create and work within a separate subdirectory. The usual COP 4530 rules apply (see Introduction/Work Rules). In particular: It is a violation of course ethics and the student honor code to use, or attempt to use, files other than those explicitly distributed in the course code library.

  5. Place all work in one file named pq.h.

  6. Turn in the files pq.h and log.txt using the submit script LIB/scripts/submit.sh and the configuration file LIB/proj8/deliverables.sh.

    Warning: The submit system uses CS email to deliver your assignment. It does not work on the program or linprog servers. Use shell.cs.fsu.edu to submit assignments. If you do not receive the second confirmation with the contents of your submission, there has been a malfunction.

Technical Requirements and Specifications

  1. Place all work in one file named pq.h. The code should use 6 distinct namespaces: std, fsu, pq1, pq2, pq3, pq4, pq5, and pq6.

  2. The first two namespaces are those encountered in the standard and course libraries. The other six are defined in the submitted code. These six namespaces define the scope of certain definitions, as shown in the following sample file documentation:

    /* pq.h
    
      Various implementations for PriorityQueue < T , P >
      organized by namespace as follows:
    
      nmsp  stbl container element order central algorithm      push     pop      front
      ----  ---- --------- ------------- -------------------    ----     ---      -----
      pq1   yes  List      unordered     fsu::g_max_element()   O(1)     O(n)     O(n)
      pq2   yes  MOList    sorted        MOList::Insert()       O(n)     O(1)     O(1)
      pq3   no   Deque     unordered     fsu::g_max_element()   AO(1)    O(n)     O(n)
      pq4   yes  Deque     unordered     fsu::g_max_element()   AO(1)    O(n)     O(n)
      pq5   yes  MOVector  sorted        MOVector::Insert()     O(n)     O(1)     O(1)
      pq6   no   Vector    heap          fsu::g_push/pop_heap() O(log n) O(log n) O(1)
    
      The pq3 version just copies the last element over the element
      to be removed, whereas the pq4 version does a leapfrog copy. Note that the
      leapfrog copy version is stable, the 1-element copy version is not.
    
    All of the pq namespaces are defined in this file.
    */
    

  3. Every method implementation must be one of three types:

    1. Type 1 (no search is required): the body consists of a single call to an operation of the underlying container

    2. Type 2 (search is required): the body uses a member function or a generic search algorithm with a minimum of ancillary code.

    3. Type 3 (heap-based): the body uses a generic heap algorithm with a minimum of ancillary code.

  4. Your submission is required to run correctly with the distributed client program tests/fpq.cpp. We will assess using fpq.cpp and another client program that uses a priority queue to sort data.

  5. The log file should contain (1) statements of the runtime of the various priority queue methods, (2) explanations [informal proofs] that your statements are correct, and (3) testing procedures and results of testing.

  6. The file level documentation should contain brief descriptions of the design for each implementation of priority queue. Please also include this in your log file.

Hints: