Question
Hash Tables Hash Table Header File Copy and paste the following code into a header file named HashTable.h Please do not alter this file in
Hash Tables
Hash Table Header File
Copy and paste the following code into a header file named HashTable.h
Please do not alter this file in any way or you may not receive credit for this lab
For this lab, you will implement each of the hash table functions whose prototypes are in HashTable.h.
Write these functions in a file named HashTable.cpp.
Please test each hash table function as you write it in a file named HashTableTest.cpp (which should include your main function).
Additionally, you will need to include your templated, doubly-linked List.h and the files Book.h and Book.cpp from Lab 7 in the same project as your Hash Table.
#ifndef HASHTABLE_H_ #define HASHTABLE_H_ #include
//destructor
HashTable(const HashTable& ht); //copy constructor /**Access Functions*/ int hash(string key); //returns the hash value for the given key //the hash value is the sum of //of the ASCII values of each char in the key //% the size the of the table //Key for this table: title + author int countBucket(int index); //counts the number of Books at this index //returns the count //pre: 0<= index < SIZE int search(Book b); //Searches for b in the table //returns the index at which b is located //returns -1 if b is not in the table /**Manipulation Procedures*/ void insert(Book b); //inserts a new book into the table //calls the hash function on the key to determine //the correct bucket void remove(Book b); //removes b from the table //calls the hash function on the key to determine //the correct bucket /**Additional Functions*/ void printBucket(int index); //Prints all the books at index //pre: 0<= index < SIZE
//Should print according to the following formula:
//"Printing index
//skips two lines
//Next, prints each book at that index in the format: //
Hash Table Constructor and Destructor
These functions should be left blank in HashTable.cpp.
The List constructor is already called inside of the HashTable.h, at the following line:
List
Likewise, the destructor should be left blank, as the List destructor will automatically be called once Table goes out of scope.
Calling the Hash Function
For the purposes of this assignment, we will be using the algorithm defined in class which sums the ASCII values of all the characters in the string key and scales the result to indices of the table.
You are welcome to use this or an alternate hash algorithm for your course project. However, please use the provided hash algorithm for Lab 8
The key that you should pass to the hash function is the Book's title concatenated with the Book's author. This key should provide enough unique information to differentiate among each book, even if the books have the same title or the same author. If both author and title are the same as another book's title and author, we can assume the book would be a duplicate entry in the table.
Adding Values to the Hash Table
The next step in the process is to be able to add a value to the hash table.
Since we are using the separate chaining approach to collisions, we are using an array of Lists to represent our table.
Each time we insert a new book into the table, we need to complete these steps:
Call the hash function to determine at which index or bucket to place the Book inside the table
Insert the Book at this index of the Table array.
Note that you need to call the correct function from the List class to insert this book onto the end of the chain of books.
Each time you insert a new book, it should be added onto the end of the chain.
Test Values for insert
You can test your insert function by making the following function calls inside main of your Hash_Table_Test.cpp:
HashTable ht; Book pp("Pride and Prejudice", "Jane Austen", 1234567, 4.95); Book c("Contact", "Carl Sagan", 99993339, 9.95); Book hg("The Hunger Games", "Suzanne Collins", 12388888, 13.55); Book hp("Harry Potter", "J.K. Rowlings", 55555678, 12.99); Book mhc("The Man in the High Castle", "Philip K Dick", 95959595, 15.95); Book bh("Bleak House", "Charles Dickens", 473890238, 8.00); ht.insert(pp); ht.insert(c); ht.insert(hg); ht.insert(mhc); ht.insert(bh);
Printing Using printBucket:
To verify your Hash Table functions are working properly, you need to be able to print the values contained in the Table.
Therefore, your next step - after writing insert - should be to write a print function.
There are two print functions you need to write for this lab; each one is used in a different way.
printBucket is used to display all of the values stored at a single bucket (a "row" in the table).
In contrast, printTable will display the first value stored at each index or bucket in the table (the "first column" in the table).
The printBucket function will allow us to dig more deeply into what is contained at a particular bucket.
You can think of printTable as providing a vertical cross section of values in the Table whereas printBucket gives us a horizontal cross section.
For example, a call to printBucket(9); in main should display the following (assuming you have inserted the values provided above).
Printing bucket: 9 The Hunger Games by Suzanne Collins $13.55 ISBN: 12388888 The Man in the High Castle by Philip K Dick $15.95 ISBN: 95959595
Printing the Hash Table Using printTable
printTable displays the first value stored at each index in the table.
If you are following along with my example, we want our printTable function to print the following to the console given the values we have already inserted:
<-----------------------> Bucket: 0 Bleak House by Charles Dickens $8.00 ISBN#: 473890238 Number of books at this bucket: 1 <-----------------------> <-----------------------> Bucket: 2 Pride and Prejudice by Jane Austen $4.95 ISBN: 1234567 Number of books at this bucket: 1 <-----------------------> <-----------------------> Bucket: 4 Contact by Carl Sagan $9.95 ISBN: 99993339 Number of books at this bucket: 1 <-----------------------> <-----------------------> Bucket: 9 The Hunger Games by Suzanne Collins $13.55 ISBN: 12388888 Number of books at this bucket: 2 <----------------------->
In other words, for each bucket in the table, we are going to output the following to the console:
<-----------------------> Bucket:
Note that this function prints nothing for a bucket containing no books.
Counting items at a bucket using the countBucket function
For this function, you will need to count the number of Books at a specific index or bucket.
Note that this function is a helper to printTable, which provides a tally of how many books are stored at each index as part of its output (see above).
Note that you will need to make use of your cursor from the List class to count how many books are stored at a particular index.
Searching the Table
Our search function will search for a particular book to determine at which bucket it is stored in the Table.
Our first step will be to call the hash function to determine which index the book would be hashed to.
Next, you will need to search through the values at this bucket to determine if the book is stored at that bucket.
Note: It will be sufficient simply to compare the isbn number of the book you are searching for to that of the books stored at that bucket to determine if that book is in the table.
If you find the book, return the bucket or index.
If the book is not in the table, your function should return -1.
Removing a Book from the Table
To remove a book, you will need to complete these steps:
Pass the book's title and author to the hash function to determine at which index this book is located.
Search for the book in the chain at that bucket
Once you have located it, call the appropriate List removal function to remove the book from that bucket .
Here is the List.h :
#ifndef LIST_H_ #define LIST_H_
#include
template
Node(listdata data) : data(data), next(NULL), previous(NULL) { } };
typedef struct Node* Nodeptr;
Nodeptr first; Nodeptr last; Nodeptr iterator; void reverse(Nodeptr node); bool isSorted(Nodeptr node); int binarySearch(int low, int high, listdata data); int size; public:
/**Constructors and Destructors*/
List(); //Default constructor; initializes and empty list //Postcondition:create a link list.
List(const List &list);
~List(); //Destructor. Frees memory allocated to the list //Postcondition:frees the memory associated with the linked list.
/**Accessors*/
listdata getFirst(); //Returns the first element in the list //Precondition:first should not be empty.
listdata getLast(); //Returns the last element in the list //Precondition:last should not be empty.
bool isEmpty(); //Determines whether a list is empty.
int getSize(); //Returns the size of the list
/**Manipulation Procedures*/
void removeLast(); //Removes the value of the last element in the list //Precondition:list should not be empty. //Postcondition:Remove the last element of the list.
void removeFirst(); //Removes the value of the first element in the list //Precondition:list should not be empty //Postcondition:Remove the last element of the list.
void insertLast(listdata data); //Inserts a new element at the end of the list //If the list is empty, the new element becomes both first and last //Postcondition:insert the new element at the end of the list.
void insertFirst(listdata data); //Inserts a new element at the start of the list //If the list is empty, the new element becomes both first and last //Postcondition:insert the new element at the beginning of the list.
/**Additional List Operations*/
void printList(); //Prints to the console the value of each element in the list sequentially //and separated by a blank space //Prints nothing if the list is empty
void startIterator(); //postcondition: set the beginning of the element equal to iterator.
void removeIterator(); // postcondition: Remove the iterator.
void insertIterator(listdata data); //precondition: list should not be empty. //postcondition: insert the new iterator.
void advanceIterator();
listdata getIterator();
bool offEnd();
bool operator==(const List &list);
void printReverse(); //Wrapper function that calls the reverse helper function to print a list in reverse //prints nothing if the List is empty
bool isSorted(); //Wrapper function that calls the isSorted helper function to determine whether //a list is sorted in ascending order. //We will consider that a list is trivially sorted if it is empty. //Therefore, no precondition is needed for this function
int getIndex(); //Indicates the index of the Node where the iterator is currently pointing //Nodes are numbered from 1 to size of the list //Pre: size != 0 //Pre: !off_end()
void advanceToIndex(int index); //Moves the iterator to the node whose index number is specified in the parameter //Pre: size != 0 //Pre: index <= size
int linearSearch(listdata data); //Searchs the list, element by element, from the start of the List to the end of the List //Returns the index of the element, if it is found in the List //Calls the above indexing functions in its implementation //Returns -1 if the element is not in the List //Pre: size != 0
int binarySearch(listdata data); //Returns the index where data is located in the List //Calls the private helper function binarySearch to perform the search //Pre: size != 0 //Pre: List is sorted (must test on a sorted list) }; template
while (temp->next != NULL) { temp = temp->next; iterator->next = new Node(temp->data); iterator = iterator->next;
} last = iterator; iterator = NULL; } } template
delete cursor;
cursor = temp; } } template
cout << temp->data << " "; temp = temp->next; } cout << endl; } template
} template
else {
Nodeptr temp = last; last = last->previous; cout << last->data << endl; delete temp; last->next = NULL; size--; } } template
if (size == 1) { delete iterator; iterator = first = last = NULL; size = 0; } else if (iterator == first) { removeFirst(); } else if (iterator == last) { removeLast(); } else { iterator->previous->next = iterator->next; iterator->next->previous = iterator->previous; delete iterator; iterator = NULL; size--; } } template
assert(size != 0); assert(index <= size); iterator = first; for (int i = 1; i < index; i++) { iterator = iterator->next; } }
template
template
advanceToIndex(mid);
if (getIterator() == data) { return mid; } else if (getIterator() > data) { return binarySearch(low, mid - 1, data); } else { return binarySearch(mid + 1, high, data); } } template
Here is the Books.h:
#include
#include
using namespace std;
class Book { private: string title; string author; unsigned isbn; double price;
public:
/**Constructors*/ Book(); Book(string t, string a, unsigned i, double p);
/**Access Functions*/ string get_title(); string get_author(); unsigned get_isbn(); double get_price();
/**Manipulation Procedures*/ void set_title(string t); void set_author(string a); void set_isbn(unsigned i); void set_price(double p);
/**Additional Functions*/
friend ostream& operator<<(ostream& os, const Book& book); //prints out a book to the designated stream in the following format //
bool operator==(const Book& book); //compares two books to determine if they are the same book
bool operator<(const Book& book); //compares two books to determine if one comes before the other //alphabetically by title and secondarily by author if the two //books contain the same title //returns false if the two books are the same
bool operator>(const Book& book); //compares two books to determine if one comes after the other //alphabetically by title and secondarily by author if the two //books contain the same title //returns false if the two books are the same
};
Book::Book():title(""), author(""), isbn(0), price(0.0){};
Book::Book(string t, string a, unsigned i, double p) { title = t; author = a; isbn = i; price = p; }
/**Access Functions*/
string Book::get_title() { return title; }
string Book::get_author() { return author; }
unsigned Book::get_isbn() { return isbn; }
double Book::get_price() { return price; }
/**Manipulation Procedures*/
void Book::set_title(string t){ title = t; }
void Book::set_author(string a) { author = a; }
void Book::set_isbn(unsigned i) { isbn = i; }
void Book::set_price(double p) { price = p; }
/**Additional Functions*/
bool Book::operator==(const Book& book) { return (title == book.title && author==book.author); }
bool Book::operator<(const Book& book) { //compares two books to determine if one comes before the other //alphabetically by title and secondarily by author if the two //books contain the same title //returns false if the two books are the same if(title == book.title && author==book.author) { return false; } else { return (title < book.title && author < book.author); } }
bool Book::operator>(const Book& book) { if(title == book.title && author==book.author) { return false; } else { return (title > book.title && author > book.author); } } ostream& operator<<(ostream& os, const Book& book)
{ os << "title:" << book.title << "/n " << "author:" << book.author << "/n" << "price:" << book.price << "/n" << "ISBN:" << book.isbn; return os;
// I am not sure is this a right way to write this function? }
#endif /* BOOK_H_ */
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started