Homework
6: OPEN HASHING and TEMPLATES in C++
- Implement open hashing with linked lists
- Use templates
- Use nested objects, destructors, and overloaded operators, AGAIN! (reinforce)
OVERALL:
The problem setting is as described in class: you are to maintain a history of all binary chromosomes seen so far. But now we will use the unsorted array to hold the current population, and a hash table (with open hashing) to store the archive of all individuals seen so far.
TEMPLATES:
Look
at the code in the files "linkedlistT.*" and "nodeT.*" . Note that
now the linked list and associated node classes are general to ANY type
of element being stored. This has a few implications:
First of all, if you look at the node class, its "print" method asks its
data item, of type ElementType, to print itself. The node class assumes
that the element of type ElementType has a "print" method.
Note that our "Individual" class has a "printchrom" but not a "print".
Give it one! (to make the node template work) Secondly, since
linked list class (the templated one) now uses the templated node class
(as opposed to the plain old node class) it must give the node template
an ElementType whenever it declares an object or ptr of type Node.
Now you can see an example use of the template! Here is the syntax
(from the insert method):
template <class ElementType>
void LinkedList<ElementType>::Insert(ElementType *elementptr) {
Node<ElementType> *newnode;
newnode = new Node<ElementType>(indi);
....
You need to make sure that every declaration of an object
or ptr of type Node, in linked list, uses the proper syntax. And
then back in hashtable.* you need to use similar syntax when declaring
objects of type LinkedList! (now that it is templated). Note
that within linkedlist.cc, we don't know yet what ElementType will be,
so we just declare nodes giving the node template "ElementType", as yet
undefined. But in hashtable, you know what the ElementType will be
when declaring your table of linked lists! Think about it.
INCLUDE GUARDS:
This
part is easy. Look at the proper use of an include guard in the file
"nodeT.h" The purpose of the guard is simply to keep a file
from being "#included" more than once, which the compiler would not like!
(Classes will be re-declared!) Note that this also prevents "infinite
include loops" which we found out in class the g++ compiler can definitely
get into! The guard works by defining a local variable (could
be any name, but must be unique to each file! one convention is to
use the file name, as used in "nodeT.h" example). Also, the guard
checks to see if this variable has been defined to the compiler already.
If so, the file must have already been included, and so the rest of the
file is skipped. See the syntax in the file "nodeT.h" These
are compiler directives ("#" in front) but you should recognize the
essential structure of an "if-then" and assignment statements:
#ifndef NODET_H
#define NODET_H
...
#endif
Make
sure you understand what is going on and do the same thing for ALL of
your files (except main!). Also make sure that all necessary files
are include SOMEWHERE!
OPERATOR OVERLOADING:
The
linked list and node templates are now generic, and use "==" "!=" and ">"
operators to compare elements. But our elements in the hashtable
are individuals! The built-in operators "==", etc. do not know how
to compare two individuals. One solution is to overload the
built-in operators with multiple meanings depending on the context in which
they are used. To do this, just create a method within the class
Individual, and name it "==" or "<" or whatever is appropriate.
See the files "individual.*"
FROM
"individual.h":
boolean Individual::operator == (Individual *other);
FROM "individual.cc":
boolean Individual::operator == (Individual *other)
{
equal(other);
};
And here is the syntax for using our overloaded operator "!= " :
template <class ElementType>
void LinkedList<ElementType>::Delete(ElementType *elementptr) {
Node<ElementType> *current,*oldcurrent;
oldcurrent = header;
current = header->next;
while( current != NULL && *(current->data) != elementptr)
)
{ oldcurrent = current; current = current->next; };
if(current != NULL)
{
oldcurrent->next = current->next;
delete current;
}
}
Now make sure that linkedlistT.cc uses the correct notation for the overloaded
operators wherever it needs to!
Entire HW6 directory (email me the path, as before).