CSCI 132 Data Structures

    Home | | Syllabus | | Assignments | | Lecture Notes

    Laboratory 8
    Due at the beginning of class, Wednesday, 4/2

    In today's lab you will experiment with the running times for different search algorithms that we learned in class.

    The code for this lab is available in the directory:

      ~csci132/labs/lab8

    Start the lab as follows:

    • Copy the code for lab8 into your labs folder by typing:
        cp -r ~csci132/labs/lab8 labs/.
    • Verify that the lab8 directory contains the following files:
      • list.h
      • list.cc
      • key.h
      • key.cc
      • search_compare.cc

    1. Comparing different search algorithms

    The search_compare.cc file has all the functions necessary to test a list of length 20 with 100 searches for random numbers within the list. The list contains only odd numbers, so successful searches are tested by searching for odd numbers and unsuccessful searches are tested by searching for even numbers. The current implementation of the function, test_search() tests the sequential_search algorithm, and prints out the total number of comparisons and average number of comparisons made for the successful and unsuccessful searches.

    To understand how this works, open the key.h file. Note that there is a public data member declared as:

      static int comparisons;
    A static variable is created once for the class and does not get recreated for each individual object that is created. Thus its value can keep track of properties that refer to the class as a whole, in this case the number of comparisons that have been made for all the Key objects created and used by the client code. Now open the key.cc file. Note that the comparisons data member is initialized to zero with the line:
      key::comparisons = 0;
    This data member is then incremented each time a comparison of keys is performed. This increment is specified in each of the overridden comparison functions given in key.cc. E.g.
      bool operator ==(const Key &x, const Key &y)
      {
        Key::comparisons++;
        return x.the_key()== y.the_key();
      }
      

    Now look at the search_compare.cc file. This program sets the list_size to 20 and the number of searches to be performed at 100. It then creates a list containing the given number of odd numbers and calls test_search().

    test_search() tests the number of comparisons performed by the sequential_search() function by setting the Key::comparisons variable to zero, and then running searches for 100 randomly selected odd numbers within the list (to test successful searches). After printing the results, test_search() then repeats this process to test for the number of comparisons performed by sequential_search() for unsuccessful searches (by searching for randomly selected even numbers). Look carefully at the test_search() function and make sure you understand the code.

    Also provided for you in the search_compare.cc file are two functions:

    • run_recursive_search_1(): Calls recursive_binary_1 with initialized values of bottom = 0, and top = the_list.size() - 1.
    • recursive_binary_1(): Performs the recursive binary search 1.

    Your task is to generalize the search_compare.cc program to do the following:

    • Change the main() function to ask the user to input a list length, and read the user's response into the list_size variable.
    • Change test_search() to print out the total and average number of comparisons for sequential search, binary search 1 and binary search 2.
    • Make sure to print out the results for successful searches for the three search functions first, then print out the results for unsuccessful searches (see the sample output below).
    • First add code to test_search() to call run_recursive_search_1() the specified number of times for successful and unsuccessful searches and print the results.
    • Add the functions:
        Error_code recursive_binary_2(const List &, const Key &, int, int, int &);
        Error_code run_recursive_search_2(const List &, const Key &, int &);

      These should implement the recursive_binary_2() function discussed in class (see below).
    • Change test_search() to call run_recursive_search_2() the specified number of times for successful and unsuccessful searches and print out the results.

    The code for recursive_binary_2() from the book is as follows:

      {
        Record data;
        if (bottom <= top) {
      	int mid = (bottom + top)/2;
      	the_list.retrieve(mid, data);
      	if (data == target) {
      		position = mid;
      		return success;
      	}
      	else if (data < target)
      		return recursive_binary_2(the_list, target, mid + 1, top, position);
      	else
      		return recursive_binary_2(the_list, target, bottom, mid - 1, position);
        }
        else return not_present;
      }
      

    The purpose of the function, run_recursive_search_2(), is to initialize the variables, bottom and top, to 0 and the_list.size() -1 when calling recursive_binary_2(). (See the implementations for binary_search_1).

    To test your code, you should compile the file, search_compare.cc. This file includes not only the list.h file, but also the list.cc file (this is necessary so that the correct object code can be created for the given List_entry type). It also includes key.h and key.cc files. Therefore, to compile use the command:

      g++ -g -Wall search_compare.cc -o search_compare

    Sample Output:
    When you are done making the modification, here is an example of what your output should look like for a user input of 15:

      radius% ./search_compare
      Enter the size of the list to test: 
      15
      Timing and testing of search algorithms on a list of size 15
      
      Testing successful comparisons for sequential search: 
      Successful Sequential Search Statistics: 
      Total number of comparisons was 868
       Average number of comparisons per search was 8.68
      
      Testing successful comparisons for binary search 1: 
      Successful Binary Search 1 Search Statistics: 
      Total number of comparisons was 492
       Average number of comparisons per search was 4.92
      
      Testing successful comparisons for binary search 2: 
      Successful Binary Search 2 Search Statistics: 
      Total number of comparisons was 548
       Average number of comparisons per search was 5.48
      
      Testing unsuccessful searches for Sequential search: 
      Unsuccessful Sequential Search Statistics: 
      Total number of comparisons was 1500
       Average number of comparisons per search was 15
      
      Testing unsuccessful searches for Binary search 1: 
      Unsuccessful Binary 1 Search Statistics: 
      Total number of comparisons was 494
       Average number of comparisons per search was 4.94
      
      Testing unsuccessful searches for Binary search 2: 
      Unsuccessful Binary 2 Search Statistics: 
      Total number of comparisons was 800
       Average number of comparisons per search was 8
      

    2. Comparing Search functions

    Run the search_compare program to answer the following questions: Write your answers on a printout of the lab8 answer sheet.

      a. What is the average number of comparisons made for each algorithm for the following values of n: 5, 10, 20, 100, 1000 ? Put your answers in the table given on the answer sheet.

      b. Explain your results for part a for a list length of 100 based on the formulas for the running time of each of the search algorithms given in the text. Do your results match what you would predict from these formulas?

        Sequential search (successful): (1/2)(n + 1)

        Sequential search (unsuccessful): n

        binary_search_1 (successful and unsuccessful): lg(n) + 1

        binary_search_2 (successful): (2(n+1)/n) lg(n+1) -3 =~ 2lg(n) -3

        binary_search_2 (unsuccessful): 2lg(n)

      Parts c - e: Run the search_compare program to answer questions in parts c - e. You will need to test multiple values of n to answer the questions.

      c. For what values of n does sequential search do fewer average comparisons than binary_search_1 for successful searches? For unsuccessful searches? (Consider all possible values of n > 0 in your answer, not simply the values given in part a.)

      d. For what values of n does sequential search do fewer average comparisons than binary_search_2 for successful searches? For unsuccessful searches? (Consider all possible values of n > 0 in your answer).

      e. For what values of n does binary_search_2 do fewer average comparisons than binary_search_1 for successful searches? For unsuccessful searches? (Consider all possible values of n > 0 in your answer).

      f. Draw the comparison trees for binary_search_1 and binary_search_2 for n = 7.

    What To Turn In.

    • A printout of the search_compare.cc file
    • Written answers to the questions in part 2. Use the lab8 answer sheet.
    • Submit your lab with the submit function: ~csci132/bin/submit csci132 lab8

    Be sure that the file prologue for each file contains your name, course, lecture section, date and purpose of the program or a description of the contents of the file (e.g. specification of the stack class).

    Reminder.
    Be sure to save a copy of each file in your labs directory. It is your responsibility to keep the copies of all programs written for this course until your graded assignment is returned.


    Home | | Syllabus | | Assignments | | Lecture Notes