Hi:
Following the interface of unordered_map, I'm trying to implement my own hash map HashMap<class KEY, class VALUE>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
template<class KEY, class VALUE>
class HashMap
{
class Node
{
KEY key;
VALUE val;
};
// bucket array; stores lists that contain key-val pairs
list<Node> * buckets;
// bucket length
int nbucket;
// hash key
unsigned int hashCode(KEY k);
// compression function
unsigned int compFunct(unsigned int);
public:
HashMap();
void insert(KEY, VALUE);
void erase(KEY);
virtual ~HashMap();
};
|
definition in the discussion:
hash code: maps key into some peculiar number
compression function: compresses the peculiar number into the range of the bucket array
I've got a few questions:
1, How do I choose nbucket? Textbook says it'd better be prime(a simple compression function given by the textbook is %nbucket). However, I don't understand why it should be a fixed number. As the hash map grows in size, ideally, the bucket array should increase accordingly to avoid more and more heavy collisions. Though, I can't seem to come up with a good way to implement this "dynamic" growth. Any idea?
2, hash code. This is a hard one, in my opinion. How can I come up with a good yet not too complicated version of harsh code? I'm thinking about using the address of variable key as the harsh code. Does that sound like a good idea? Why and why not?
Edit:
I've found it's not a good idea because I'll always have the same address of the parameter KEY key on stack of int hashCode(KEY);
Here's the update of the question:
How can I convert a variable of any type to an int or something? Essentially, I need to implement the Object.hashCode() in java.
I'm thinking about taking, say, the lowest 32 bits of KEY key, regardless of its type. But << and >> operators don't seem to work all the time. How can I do this?
Below is what I've got (with errors):
1 2 3 4 5 6 7 8 9 10
|
template<class KEY, class VALUE>
unsigned int HashMap<KEY, VALUE>::hashCode(KEY key)
{
unsigned int k = key & 0xffffffff; //error: no match for ‘operator&’ in ‘key & 4294967295u’
k += ~(k<<9);
k ^= (k>>14);
k += (k<<4);
k ^= (k>>10);
return k;
};
|
3, I had intended to derive my class HashMap from map in stl, but found map didn't have a virtual destructor, which makes it a bad idea to derive a class from it. I don't understand why those people did this. Is there any strong reason for them to prevent people from inheriting from map?
Many thanks in advance!