Homework 4: Priority Queues

Generic implementations of priority queue

Due: 04/24/05

Educational Objectives: Experience applying the following concepts: associative generic containers; generic algorithms; priority queue; and developing and testing multiple implementations using namespace.

Operational Objectives: Design and implement eight (8) distinct implementations of the Priority Queue template TPriorityQueue<T,P> based on TVector<T> (3), TDeque<T> (3), and TList<T> (2). Use namespaces tpq1, tpq2, ... , tpq8 to scope the eight variations and use namespace alt to scope the generic algorithms required for some of the implementations. The work must operate correctly with the supplied test client ftpq.cpp and meet all other requirements listed below.

Deliverables: One file tpq.h

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 (as usual for our course library):

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 Trees 1 in the context of heaps, heap algorithms, and heap sort. 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_simple_sort() with g_heap_sort() for example.)

The current project will build priority queues using (1) one of our familiar p-Containers TVector<T>, TDeque<T>, TList<T> as the data storage facility; (2) possibly some associative structure on the data (an ordering); and (3) an appropriate generic algorithm for the search mechanism. In the case of heap-based priority queues (cases 7 and 8) two generic algorithms will be required.

Procedural Requirements

  1. Create and work within a separate subdirectory (called proj below). Make sure your code distribution directories are up to date by invoking your "update" command. 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.

  2. Place all work in one file named tpq.h.

  3. Turn in the file tpq.h using the pr4submit.sh script.

    Warning: Submit scripts do not work on the program and linprog servers. Use shell.cs.fsu.edu to submit projects. If you do not receive the second confirmation with the contents of your project, there has been a malfunction.

Technical Requirements and Specifications

  1. Place all work in one file named tpq.h. The code should use 11 distinct namespaces: std, fsu, alt, tpq1, tpq2, tpq3, tpq4, tpq5, tpq6, tpq7, and tpq8.

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

    /* tpq.h
    
      Various implementations for TPriorityQueue < T , P >
      organized by namespace as follows:
    
      nmsp  stbl container element order generic algorithms     push     pop      front
      ----  ---- --------- ------------- ------------------     ----     ---      -----
      tpq1  y    vector    unordered     fsu::g_max_element()   O(1)     O(n)     O(n)
      tpq1a n    vector    unordered     fsu::g_max_element()   O(1)     O(n)     O(n)
      tpq2  y    vector    sorted        fsu::g_lower_bound()   O(n)     O(1)     O(1)
      tpq3  y    deque     unordered     fsu::g_max_element()   O(1)     O(n)     O(n)
      tpq3a n    deque     unordered     fsu::g_max_element()   O(1)     O(n)     O(n)
      tpq4  y    deque     sorted        fsu::g_lower_bound()   O(n)     O(1)     O(1)
      tpq5  y    list      unordered     fsu::g_max_element()   O(1)     O(n)     O(n)
      tpq6  y    list      sorted        alt::g_lower_bound()   O(n)     O(1)     O(1)
      tpq7  n    vector    partial       fsu::g_push/pop_heap() O(log n) O(log n) O(1)
      tpq8  n    deque     partial       fsu::g_push/pop_heap() O(log n) O(log n) O(1)
    
      The "a" versions of tpq1 and tpq3 just copy the last element over the element
      to be removed, whereas the reqular versions do a leapfrog copy. Note that the
      latter is stable, the former is not.
    
    The namespace alt contains the generic algorithm:
    
      template <class ForwardIterator, typename ElementType, class Comparator>
      ForwardIterator g_lower_bound (ForwardIterator beg,  ForwardIterator end,
                                     const ElementType& x, const Comparator& cmp)
    
    This version of lower bound uses the assumption of an ordered range (as in the
    classic version) but works for forward iterators. Thus, (1) it can be applied to
    TListIterators and (2) it has runtime O(n) rather than O(log n) (where n = size).
    
    All other generic algorithms needed are in the fsu namespace and are in the code
    libray.
    
    All of the tpq namespaces as well as the alt namespace 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 generic search algorithm (as specified in the table above) 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/ftpq.cpp.

Hints: