Sonoma State University
 
Algorithm Analysis
Instructor: Henry M. Walker

Lecturer, Sonoma State University
Professor Emeritus of Computer Science and Mathematics, Grinnell College

Although CS 415 has been well developed for several years, last year the CS faculty made a significant, long-term curricular change regarding SSU's Upper Division GE Area B Requirement.

Assignment on Topological Sorting, Partition, and Quicksort

As suggested by this assignment's title, this exercise is organized into three parts:

Topological Sorting

  1. Consider the following directed three graphs.

    a directed graph    another directed graph    another directed graph
    Directed Graph 1 Directed Graph 2 Directed Graph 3

    For each of these graphs, answer the following:

The Partition Procedure and Alternative Loop Invariants

The Reading on Quicksort discusses four possible loop invariants for the Partition Problem, each based on using the left element in an array segment as a pivot. A similar, but alternative, approach uses the right element in an array segment as a pivot. This alternative considers three additional loop invariants.

3 loop invariants with right pivot
  1. Based on the Reading on Quicksort, the program partitions-alt.c provides

    1. Review the program and explain

      • the purpose of the code
          typedef struct algs {
             char * name;
             int (*proc) (int [ ], int, int, int);
          } partitionType;
                    
        and how this structure is used.
      • the purpose of the line

        #define printCopyTime 0  // 1 =  print times to copy arrays; 0 = omit this output
                    
        and how printCopyTime is used.
      • what steps are involved to time segments of code in C/C++ (be sure to identify what function(s) is(are) called).

      • explain the purpose of variables, maxreps and copy_time, and why these variables are needed.

    2. Expand this program by inserting the following two functions and updating the main procedure to include them in test runs:

      • a procedure that implements Loop Invariant 5, given above
      • a procedure that implements Loop Invariant 7, also given above

      Note: Both of these procedures must be based on the Loop Invariants specified. Procedures violating the specified Loop Invariant will lose [almost] all credit for that part.

    3. After running the expanded program from Step 2, turn in a copy of the output obtained, and answer these questions.

      • Which, if any, of the implementations of the partition are most efficient? Why do you think this result is observed?
      • Roughly, how do the times change for each procedure, when the data sets double in size with each main iteration? Does this experimental timing suggest Big-O or Big-θ for the run-time? Explain.
  2. Finding the kth smallest item: The partition method may be used to find the kth smallest element in an array, by narrowing the range to be examined within the overall array. For example, suppose that partition returns index middle as the location of the final location for the pivot. Basic processing involves three cases:

    Write a procedure kthSmallest to find the kth smallest element in any array. kthSmallest should use procedure partition and the above notes the above algorithm to guide its processing. Your lab write up should include the code for kthSmallest, the enclosing program used for testing, and the test runs used for checking correctness.

    Note: For an array of size n, setting k to n/2 enables kthSmallest to find the median value.

Notes on Steps 2 and 3: For Steps 2 and 3 in this assignment, you should submit:

Quicksort, Improved Quicksort, and Hybrid Quicksort

  1. Program quicksort-comparisons.c contains two copies of quicksort procedures and a framework for timing the running of these procedures on ascending, random, and descending data sets of varying sizes. In particular,

    These functions come directly from the Reading on Quicksort

    1. Revise the relevant function(s) labeled "impr", to transform the code to implement an "improved quicksort". In brief, an "improved quicksort" modifies the "basic quicksort" by selecting a random element in the array segment between index left and right, and swapping that element with the element at array index left. Otherwise, the "improved quicksort" is the same as the "basic" version.
    2. Run the program and describe what happens. Why do you think the program crashes on ascending and/or descending data for the basic quicksort, once the data set gets to a certain size?
    3. Modify the testing component of the main procedure, so that the basic quicksort component is run only for ascending or decreasing data sets of relatively small size, but times for those data sets are given only as "---" for larger data sets. The full program still should produce timing output for the basic quicksort for all sizes of random data and for the improved quicksort for all data sets. For example, part of the output might have the following format (although the numbers may be [quite] different).
                          Data Set                   Times
      Algorithm             Size     Ascending Order   Random Order  Descending Order
      basic quicksort      40000          1.1  ok        0.0  ok           1.1  ok
      improved quicksort   40000          1.1  ok        0.0  ok           1.1  ok
      
      . . .
                          
      basic quicksort     160000         18.1  ok        0.0  ok          18.0  ok
      improved quicksort  160000         17.9  ok        0.0  ok          18.0  ok
      
      basic quicksort     320000         ----            0.0  ok          ----
      improved quicksort  320000          0.0  ok        0.0  ok          0.0  ok
      
      . . .
                          
      basic quicksort    2560000         ----            0.4  ok          ----
      improved quicksort 2560000          0.2  ok        0.4  ok          0.2  ok
      
      . . .
              
    4. Review the output produced by this updated program (and turn it in with the revised program and other answers to this assignment). Under what circumstances, if any, does the improved quicksort yield better results than the basic version? Explain these results briefly, based on your program runs.
  2. Expand the program in Step 4 to include a hybrid quicksort function (with any needed helper functions—perhaps copied with minor revision from the improved quicksort). The hybrid quicksort, is described in the Reading on Quicksort.

    1. The expanded program should include these elements:
      • The revised hybrid quicksort function should include another parameter—the maximum size of the array segment for an insertion sort (before the improved quicksort is used).
      • For each data set, the main program should call the hybrid quicksort with the maximum size for the insertion sort having values 4, 5, 6, . . . 11.
      • The maximum sized data set should be set as 40960000
    2. Print out the results of a sample run of this program, and answer these questions:
      • For which array-segment sizes, if any, does the insertion sort improve the performance of the hybrid quicksort?
      • What optimal size of an array segment should be used for an insertion sort, rather than a quicksort, in this hybrid algorithm? Explain briefly.

Notes on Steps 4 and 5: Since Step 5 extends Step 4,

created August 6, 2022
revised August 9, 2022
revised September 27, 2022
revised December 30, 2022
revised Summer, 2023
revised Novemver 30, 2024
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.