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;
size_t size( ) const { return total_records; }
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;
Node *link; };
Use the following type for all records:
struct MyRecType {
int key;
int data; };
Table<MyRecType> mytable; MyRecType myrec; myrec.data = 12; myrec.key = 5; mytable.insert(myrec);
bool found_it; Table<MyRecType> mytable; found_it = mytable.is_present(5);
T = 1 + a/2
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
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().
// 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))
node_ptr = node_ptr->link;
return ( node_ptr!=NULL );
}
Insertion sort.
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.
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);
}
}
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