Node hashTable[10];
保持其内容未初始化。这使得hashInserta bit more of an adventure 中的一些东西比你想在计算机程序中看到的要多。使用
Node hashTable[10] = {};
到Zero Initialize 数组并获得更多可预测性。
但这并不能解决所有问题。零初始化会将 empty 设置为 false,但事实并非如此。您需要一个默认构造函数(或成员上的 default member initializers)将值强制为 true 或反转逻辑。
当您仔细研究这两种方法时,您会意识到empty 标志是唯一需要的,因为列表中的第一个节点可能未使用。但是如果不需要第一个节点,如果没有第一个节点怎么办? empty 的作业可以用空指针来处理。
Node * hashTable[10] = {}; // treat each entry in the hash table like a next
// without the rest of the node
这可以让您将hashInsert 缩小到
void hashInsert(Node * table[], string word) {
int index = 5; //should add hashFunction() if not testing
Node *current = table[index]; //
if (table[index] == nullptr)
{
table[index] = new Node{word, nullptr};
}
else
{
while (current->next != nullptr)
{
current = current->next;
}
current = new Node{word, nullptr};
}
}
注意: Node{word, nullptr}; 使用aggregate initialization 允许我们创建Node 并一次性设置其所有成员。非常方便。
但这不起作用,因为current 是一个局部作用域的自动变量,所以分配给它的新Node 在函数返回时就会丢失。我们需要更智能的东西。
Ranoiaetep 建议 current->next = new Node();。这会起作用,但我们可以变得更聪明。
void hashInsert(Node * table[], string word) {
int index = 5; //should add hashFunction() if not testing
Node **current = &table[index]; // point at the next pointer! Now we know
// the correct place to insert in ALL cases
if (*current == nullptr)
{
*current = new Node{word, nullptr};
}
else
{
while (*current != nullptr)
{
current = &(*current)->next;
}
*current = new Node{word, nullptr};
}
}
在这个版本中,您可能会注意到if (*current == nullptr) 和while (*current != nullptr) 并没有那么不同。在if 中我们在没有节点时添加一个新节点。在while 中,我们寻找没有节点,然后添加一个新节点。无论哪种方式,没有节点意味着添加一个节点。我们或许可以将它们结合起来。
void hashInsert(Node * table[], string word) {
int index = 5; //should add hashFunction() if not testing
Node **current = &table[index];
while (*current != nullptr) // look for end of list
{
current = &(*current)->next;
}
*current = new Node{word, nullptr}; // add to end of list
}
哇。 4 行代码和几个大括号。
整体看起来像
#include <iostream>
using namespace std;
struct Node {
string word;
Node *next;
};
void hashInsert(Node * table[], string word) {
int index = 5; //should add hashFunction() if not testing
Node **current = &table[index];
while (*current != nullptr)
{
current = &(*current)->next;
}
*current = new Node{word, nullptr};
}
int main() {
Node * hashTable[10] = {};
hashInsert(hashTable, "test");
hashInsert(hashTable, "test");
cout << hashTable[5]->next->word;
}