// FILE: Table.h // TEMPLATE CLASS PROVIDED: Table // This class is a container template class for a Table of records. // The template parameter, RecordType, is the data type of the records in the // Table. It may any type with a default constructor, a copy constructor, // an assignment operator, and an integer member variable called key. // // CONSTRUCTOR for the Table template class: // Table(int capacity) // Postcondition: The Table has been initialized as an empty Table. // // MODIFICATION MEMBER FUNCTIONS for the Table class: // void insert(const RecordType& entry) // Precondition: entry.key >= 0. Also if entry.key is not already a key in // the table, then the Table has space for another record // (i.e., size( ) < capacity). // Postcondition: If the table already had a record with a key equal to // entry.key, then that record is replaced by entry. Otherwise, entry has // been added as a new record of the Table. // // void remove(int key) // Postcondition: If a record was in the Table with the specified key, then // that record has been removed; otherwise the table is unchanged. // // CONSTANT MEMBER FUNCTIONS for the Table class: // bool is_present(const Item& target) 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. // // void find(int key, bool& found, RecordType& result) const // Postcondition: If a record is in the Table with the specified key, then // found is true and result is set to a copy of the record with that key. // Otherwise found is false and the result contains garbage. // // size_t size( ) const // Postcondition: Return value is the total number of records in the // Table. // // VALUE SEMANTICS for the Table template class: // Assignments and the copy constructor may be used with Table objects. #ifndef TABLE_H #define TABLE_H #include // Provides size_t template class Table { public: // CONSTRUCTOR Table(int capacity); // DESTRUCTOR ~Table(); // MODIFICATION FUNCTIONS void insert(const RecordType& entry); void remove(int key); Table & operator = (const Table &source); // CONSTANT FUNCTIONS bool is_present(int key) const; void find(int key, bool& found, RecordType& result) const; size_t size( ) const { return used; } private: RecordType *data; size_t capacity ; //So operator= will know if data already allocated size_t used; // HELPER FUNCTIONS size_t hash(int key) const; size_t next_index(size_t index) const; void find_index(int key, bool& found, size_t& i) const; }; // TEMPLATE CLASS IMPLEMENTED: Table // INVARIANT for the Table ADT: // 1. The number of records in the Table is in the member variable used. // 2. The actual records of the table are stored in the array data, with // a maximum of "capacity" entries. Each used spot in the array has a // non-negative key. Any unused record in the array has a key field of // -1 (if it has never been used) or -2 (if it once was used, but is // now vacant). #include // Provides assert #include // Provides size_t template Table::Table(int cap) // Library facilities used: stdlib.h { size_t i; capacity = cap; data = new RecordType[capacity]; used = 0; for (i = 0; i < capacity; i++) data[i].key = -1; // Indicates a spot that's never been used } template Table::~Table() { delete [] data; } template void Table::insert(const RecordType& entry) // Library facilities used: assert.h { bool already_present; // True if entry.key is already in the table size_t index; // data[index] is location for the new entry assert(entry.key >= 0); // Set index so that data[index] is the spot to place the new entry find_index(entry.key, already_present, index); // If the key wasn't already there, then find the location for the new entry if (!already_present) { assert(size( ) < capacity); index = hash(entry.key); while (data[index].key >= 0) index = next_index(index); used++; } data[index] = entry; } template void Table::remove(int key) // Library facilities used: assert.h { bool found; // True if key occurs somewhere in the table size_t index; // Spot where data[index].key == key assert(key >= 0); find_index(key, found, index); if (found) { // The key was found, so remove this record and reduce used by one data[index].key = -2; // Indicates a spot that's no longer in use used--; } } template bool Table::is_present(int key) const // Library facilities used: assert.h, stdlib.h { bool found; size_t index; assert(key >= 0); find_index(key, found, index); return found; } template void Table::find(int key, bool& found, RecordType& result) const // Library facilities used: stdlib.h { size_t index; find_index(key, found, index); if (found) result = data[index]; } template size_t Table::hash(int key) const // Library facilities used: stdlib.h { return (key % capacity); } template size_t Table::next_index(size_t index) const // Library facilities used: stdlib.h { return ((index+1) % capacity); } template void Table::find_index(int key, bool& found, size_t& i) const // Library facilities used: stdlib.h { size_t count; // Number of entries that have been examined count = 0; i = hash(key); while((count < capacity) && (data[i].key != -1) && (data[i].key != key)) { count++; i = next_index(i); } found = (data[i].key == key); } #endif template Table & Table::operator = (const Table &source) { capacity = source.capacity; if (capacity > 0) delete [] data; data = new RecordType[capacity]; for (int i=0; i