Если бы это была не домашняя работа (это был твой тег?), Я бы порекомендовал одну unordered_map или карту.Вы понимаете, что это еще не сойдет вместе - лучше всего упростить это и заняться чем-то одним, а не откусывать больше, чем вы можете пережевать.Если вам нужна хэш-карта деревьев, я предлагаю вам начать строить ее из контейнеров C ++ STL, на которые вы можете положиться, а затем - если вы не должны использовать их для этой задачи - заменить их одно за другим, убедившись, чтовы используете высокоуровневое использование / тесты, работая так, как вы это делаете.Это означает:
typedef vector<map<T> > Container;
Container container;
Вы можете использовать container.resize (n), чтобы заполнить контейнер n пустыми картами, или увеличить контейнер с предыдущего размера до нового с дополнительными пустыми картами.
Действительно, начните с этого.Затем, если вам нужно в качестве упражнения, реализовать каждый вектор и карту независимо, и проверить их использование с помощью простых независимых тестовых примеров, прежде чем вставлять их обратно в вашу гибридную хэш-карту.
Может показаться, что янемного грубоват, поэтому давайте разберем немного вашего вопроса, чтобы увидеть некоторые заблуждения, о которых я говорил:
В любом случае, мне трудно понять, как сделать некоторые вещиНапример, установка хеш-таблицы, представляющей собой массив со значением NULL, а также создание BST-объектов memcpy из одной таблицы в другую.
Мой совет - не усложняйте и делайте то, что очевидно и чисто.Если вы должны использовать массив, а не вектор, то если он в стеке:
X* buckets[N];
for (int i = 0; i < sizeof buckets / sizeof buckets[0]; ++i)
array[i] = NULL;
Если он в куче:
X** p_buckets = new X*[N];
for (int i = 0; i < N; ++i)
array[i] = NULL;
Это медленнее, чем memset (),но это просто и понятно, и у вас появляется привычка думать о том, как перебирать контейнер, выполняя нужные операции.Для этого есть больше способов на C ++, но те же стили итерации труднее использовать для других произвольных задач, поэтому придерживайтесь этого, пока не освоитесь с ним полностью.
BST * prevData;BST * currData;
Насколько я понимаю, я думаю, что мне нужно перегрузить операторы = и ==, чтобы разрешить установку элементов массива в NULL, это правильно?Мне действительно неясно, как реализовать все это, но на примерах от Google я получил:
BST & BST :: operator = (int null);bool BST :: operator == (int null);Перегрузка оператора == предназначена для проверки, равен ли индекс конкретного массива NULL.Я предполагаю, что мне нужен какой-то дополнительный код, а не только прототипы, и вот тут я отклеиваюсь.
У вас есть два указателя на BST.Ваши хеш-таблицы представляют собой массив таких объектов, но только один из ваших комментариев предлагает вам представить их как указатели на две такие хеш-таблицы (вместо того, чтобы называть их временными переменными, записывающими ненулевые элементы во время итерации по хеш-таблице).Они должны быть BST **, так как они указывают на первый BST * в хэш-таблице.Но это очень опасный способ реализации ваших хеш-таблиц, так как клиент использует указатель на хеш-таблицу, а не указатель на некоторый класс, который обеспечивает безопасную реализацию концепции хеш-таблицы.С таким указателем все, что они могут сделать, - это индексировать конкретный BST, но нет связи ни с функциями, которые вы намереваетесь поддерживать хеш-таблицей, ни с переменными, которые отслеживают, сколько сегментов у него в настоящее время есть, сколько элементов в немсодержит и т. д. Вы должны поместить свои массивы в класс, который предоставляет все это;Есть много дизайнерских решений, но это должно выглядеть примерно так:
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_;
};
(опять же, я могу только рекомендовать сначала попробовать это с заменой p_ на этот вектор карт).
Второй момент - это memcpy, что мне не разрешено делать компилятором.
memcpy (prevData [x], currData [x], sizeof (BST) * height);
Жалуется на
ошибка C2664: 'memcpy': невозможно преобразовать параметр 1 из 'BST' в 'void *'Отсутствует пользовательский оператор преобразования, который мог бы выполнить это преобразование, или оператор не может быть вызван
Это очень странный запрос - скопировать все из одного сегмента в одной хэш-таблице в тот же блок в другом.хеш-таблица.Если, например, количество сегментов отличается или хеш-функция отличается, то вы, вероятно, испортите целевой контейнер.В любом случае, я предлагаю вам реализовать класс BST с семантикой значений (т. Е. Конструктор копирования и оператор =, который копирует существующее дерево).Тогда вы можете просто использовать:
prevData.buckets[x] = currData.buckets[x];
(примечание: оператор должен искать в хеш-таблице, и, учитывая, что тип ключа должен быть в состоянии int, вы не хотите использовать ту же записьдля копирования целых сегментов - вы не можете перегрузить функцию, если обе имеют одну и ту же сигнатуру. Вот почему здесь я показываю, что сегменты являются открытым контейнером BST-файлов - это раскрывает инкапсуляцию, а в реальных классах просто не нужно, чтобы пользователи даже зналиведра (или BST в этом отношении)).