If it wasn't homework (that was your tag?) I'd recommend a single unordered_map or map. You're conception of this isn't coming together yet - best to simplify it and tackle one thing at a time rather than biting off more than you can chew. If you want a hash map of trees, I suggest you start building that from the C++ STL containers that you can rely on to work, then - if you're not supposed to use them for this task - replace them one by one making sure you keep the high-level usage/tests working as you do it. That means:
typedef vector<map<T> > Container;
Container container;
You can use container.resize(n) to fill the container with n empty maps, or to grow the container from some previous size to a new one with the extra maps being empty.
Really, start with that. Then if you have to as an exercise, implement each of the vector and map independently, and test their usage with simple indepedent test cases before slotting them back into your hybrid hash map.
It may sound like I'm being a bit harsh, so lets work through a bit of your question to see some of the mis-conceptions of which I spoke:
Anyway, I'm having trouble figuring
out how to do some things, such as
setting the hash table, which is an
array to NULL, and also memcpy'ing BST
objects from one table to another.
My advice is keep things simple and do what's obvious and clean. If you must use an array and not a vector, then if it's on the stack:
X* buckets[N];
for (int i = 0; i < sizeof buckets / sizeof buckets[0]; ++i)
array[i] = NULL;
If it's on the heap:
X** p_buckets = new X*[N];
for (int i = 0; i < N; ++i)
array[i] = NULL;
This is slower than memset(), but it's simple and understandable, and gets you in the habit of thinking about looping over your container, doing the operations you want. There are more C++ ways to this, but it's harder to use those same styles of iteration for other arbitrary tasks, so stick to this until you're totally comfortable with it.
BST *prevData;
BST *currData;
As I understand it, I think I have to overload the = and == operators to allow setting
array elements to NULL, is this correct? I'm really unclear about how to implement all
this, but going on examples from Google, I've got:
BST& BST :: operator= (int null);
bool BST :: operator== (int null);
The == operator overload is to check whether a specific array index is equal to NULL.
I'm assuming I need some additional code, rather than just the prototypes, and this is
where I come unstuck.
You've got two pointers to BSTs. Your hash tables are an array of such objects, but it's only one of your comment that suggests you conceive of these as pointers to two such hash tables (rather than say being temporary variables recording non-NULL elements during iteration through the hash table). They should be BST*, as they point to the first BST in the hash table. But, this is a very dangerous way to implement your hash tables, as the client is using a pointer to the hash table rather than a pointer to some class that provides a safe implementation of the hash table concept. With such a pointer, all they can do is index to a specific BST, but there's no association with the functions that you intend to maintain the hash table, nor the variables that track how many buckets it currently has space for, how many elements it contains, etc.. You should put your arrays into a class that provides all this; there are lots of design decisions, but it should look something like this:
template <typename Key, typename Value>
class Hash
{
public:
Hash() : p_(NULL), size_(0), num_buckets_(0) { }
// find/make entry for Key, giving read/write access to the current/a-default value
Value& operator[](const Key&);
const Value& operator[](const Key&) const;
// try to find an entry, throw an exception if not found...
Value& at(const Key&);
const Value& at(const Key&) const;
// report whether a key is already in the hash table...
bool has_key(const Key&) const;
int size() const;
private:
BST* p_;
int num_buckets_;
int size_;
};
(yet again, I can only recommend that you first try this with p_ replaced with that vector of maps).
The second point is memcpy, which I'm not being allowed to do by the compiler.
memcpy(prevData[x], currData[x], sizeof(BST) * height);
Complains about
error C2664: 'memcpy' : cannot convert parameter 1 from 'BST' to 'void *'
No user-defined-conversion operator available that can perform this conversion, or
the operator cannot be called
It's a very bizarre request to copy everything from one bucket in one hash table into the same bucket in another hash table. If, for example, the number of buckets differs or the hash function differs then you'll probably corrupt the destination bucket. Anyway, I suggest you implement a BST class with value semantics (i.e. a copy constructor and operator= that replicates an existing tree). Then you can simply use:
prevData.buckets[x] = currData.buckets[x];
(note: operator should look up in the hash table, and given the key type ought to be able to be int, you don't want to use the same notation for copying entire buckets - you can't overload a function if both have the same signature. That's why here I show buckets being the exposed container of BSTs - exposing this breaks encapsulation; in real classes you just don't want users even aware of the buckets (or BSTs for that matter)).