## CS 2005, B Term 1999 Data Structures and Programming Techniques Solutions to the Practice Problems for Test 3

Instructions.   Read each problem carefully. Write your solutions in ink in the spaces provided. Write neatly and explain your answers as clearly as possible.

Refer to the Table class definition that appears below.

```    template <class RecordType>
class Table {
public:
// MEMBER CONSTANT
static const size_t TABLE_SIZE = 811;
// CONSTRUCTORS and DESTRUCTOR
Table( );
Table(const Table& source);
~Table( );
// MODIFICATION MEMBER FUNCTIONS
void insert(const RecordType& entry);
void remove(int key);
void operator =(const Table& source);
// CONSTANT MEMBER FUNCTIONS
void find(int key, bool& found, RecordType& result) const;
bool is_present(int key) const;
private:
Node<RecordType> *data[TABLE_SIZE];
size_t total_records;
// HELPER FUNCTION
size_t hash(int key) const;
Node<RecordType>* find_node(int key) const; };
```
Assume the following Node template declaration:
```    template <class Item>
struct Node     {
Item data;
```
Use the following type for all records:
```   struct MyRecType {
int key;
int data;     };
```

1. For each of the following, write a C++ program segment that accomplishes the stated objective. Table accesses must use only the public members of the Table class. Declare all variables used in your program segment.

• Declares a Table (see above for record type) named mytable and inserts the data value 12 with a key value of 5 into mytable.
```Table<MyRecType> mytable;
MyRecType myrec;
myrec.data = 12;
myrec.key = 5;
mytable.insert(myrec);

```

• Assigns the value true to the variable found_it if there is a record with a key value of 5 in the Table named mytable. Assigns false to found_it otherwise. The table must be declared but you may assume that it is initialized elsewhere in the program.
```bool found_it;
Table<MyRecType> mytable;
found_it = mytable.is_present(5);

```

• State the formula that gives the (approximate) average search time for chained hashing in terms of the load factor a.
```T = 1 + a/2

```
• Recall that the average search time for open-address hashing with basic linear probing is T = (1/2) (1 + 1/(1-a)), where a is the load factor. Calculate the average search time for a table with a storage array of 1200 positions, of which 800 are occupied.
```The load factor is a = 800/1200 = 2/3 in this case,
so the average search time is
T = (1/2) (1 + 1/(1-2/3)) = (1/2) (1 + 1/(1/3)) = 2

```
• Calculate the big-O running time of the following function half() in terms of n.
```size_t half(size_t n) {
if (n <= 1) return 0;
else return half(n/2); }

The function half() is recursive. Each level of the recursion
takes time O(1). Thus, the total running time is of the order
of the recursion depth. Each recursive call divides n by a
factor of 2. The recursion stops after this repeated division
by 2 yields a result of 1 or less. This takes O(log2 n) steps.
The latter expression gives the running time for half().

```

2. Implement the Table member function is_present() specified below without using any linked list toolkit functions. Use the private member variables defined above. Note that this is a chained hashing implementation.
```//   bool is_present(const int& targetkey) const
//     Postcondition: The return value is true if there is a record in the
//     Table with the specified key. Otherwise, the return value is false.

template <class RecordType>
bool Table<RecordType>::is_present(const int& targetkey) const {
size_t index = hash(targetkey);
Node<RecordType> *node_ptr = data[index];
while ((node_ptr!=NULL) && ((node_ptr->data).key!=targetkey))
return ( node_ptr!=NULL );
}
```

3. Suppose you've taken on a job as a grader in the CS department. The 30 exams you've just graded are sitting in a randomly ordered pile on your desk. The professor (your boss) has asked you to return the graded exams to him/her in a sorted pile, with the highest grades at the top of the pile.

• One method you can use is to transfer the exams from the unsorted pile to a second, sorted, pile one exam at a time, placing each exam from the first pile in its correct location in the second pile at each step. What sorting method covered in class does this correspond to?
```Insertion sort.

```

• Calculate exactly how many steps are required to sort the 30 exams using the method described above, in the worst case. The unsorted pile should be thought of as a stack, with access only from the top. The second pile should be thought of as a list with a cursor, as in HW3. Examining the current exam in the sorted pile and comparing its score to that of the exam currently on top of the unsorted pile counts as one step. Moving the exam currently at the top of the unsorted pile to some location in the sorted pile counts as an additional step.
```30 steps are needed just to move the exams from the unsorted pile to the
sorted pile (not counting any actual sorting).

In the worst case, the k-th exam from the unsorted pile can be placed
in the sorted pile only after examining all k-1 exams previously placed
in the sorted pile. This requires k-1 steps. k varies from 1 to 30,
so the number of steps required for this is the sum from k=1 to 30 of (k-1),
i.e. the sum 1 + 2 + 3 + ... + 29, which is 29*30/2 = 435.

Adding the 30 steps required for moving, the total number of steps is 465.
```

4. Fill in the blanks below to obtain a correct implementation of the quicksort algorithm. Assume that the partition function returns the correct value in the pivot_index argument.
```void quicksort(int data[ ], size_t n)
{
size_t pivot_index; // Array index for the pivot element
size_t n1;          // Number of elements before the pivot element
size_t n2;          // Number of elements after the pivot element

if (n > 1)
{
// Partition the array, and set the pivot index
partition(data, n, pivot_index);

// Compute the sizes of the subarrays
n1 = pivot_index;
n2 = n - n1 - 1;

// Recursive calls to sort the subarrays
quicksort(data, n1);
quicksort((data + pivot_index + 1), n2);
}
}

```

5. Circle all true statements among those on the following list:
```   Every AVL tree is balanced in the sense that all of
its leaf nodes are at the same depth.

-->Insertion sort is faster than mergesort for array sizes
less than 20 or so.

A derived class inherits all members of the base class
as public members.

-->A graph with n nodes has an adjacency matrix of size nxn

```