哈希表 - 链表数组 - C++

Posted

技术标签:

【中文标题】哈希表 - 链表数组 - C++【英文标题】:Hash-table - Array of Linked-list - C++ 【发布时间】:2013-01-05 15:29:09 【问题描述】:

我正在尝试通过在链接节点上使用数组(制作链接列表)来创建哈希表。 但是我在将值插入哈希表时遇到了困难。当我运行它时,我得到了这个:

http://gyazo.com/3a28a70e66b3ea34e08223e5948f49c0.png

这是我的代码:

#include <iostream>
using namespace std;

class Node 
public:
  int num;
  Node * next;
;

class intHashTable 
private:
  int size;
  Node ** table;
public:
  intHashTable(int size);  // construct a new hash table with size elements
  ~intHashTable();     // delete the memory for all internal components
  void insert(int num);    // insert num into the hash table, no effect
               // if num is already in table
  void remove(int num);    // remove num from the hash table, no effect if not in table
  int lookup(int num);     // return 1 if num is already in table, 0 otherwise
  void print(void);        // print the elements of the hash table to the screen
;

// construct a new hash table with nelements elements
intHashTable::intHashTable(int nelements)

  size = nelements;
  table = new Node*[size];
  for ( int i = 0; i < size; i++ ) 
    table[i] = NULL;
  


intHashTable::~intHashTable()

   for(int i=0; i<size; i++)
   
      Node* temp = table[i];
      while(temp != NULL)
      
         Node* next = temp->next;
         delete temp;
         temp = next;
      
   
   size = 0;
   delete[] table;


void intHashTable::insert(int num)
    int location = ((unsigned)num) % size;
    Node *runner = table[location];
    if(runner == NULL )
    runner->num = num;
     else
        while(runner != NULL )
            runner = runner->next;
        
        runner->num = num;
    
   

int main()
    intHashTable a (10);
    a.insert(2);
    return 0;

【问题讨论】:

Code::Blocks 中有调试器吗?它会告诉你出了什么问题... 在insert中,runner = table[location]基本上是NULL吧? 在调试器中运行时没有错误或警告或方便的堆栈跟踪? 1 条友好的 :) 建议 - 使用调试器会让你比其他不使用调试器的学生更有优势 - 这是我在面试时经常问的问题。 另外,你的名字在屏幕截图中,如果这让你感到困扰,ayokunle。 【参考方案1】:

intHashTable构造完成后,table的所有元素仍然是NULL。但是,在函数insert 中,一个元素被取消引用:

Node *runner = table[location];
runner = runner->next;

这会使程序崩溃,因为it is illegal to dereference a null pointer。

【讨论】:

and if(runner == NULL) runner->num = num; @Caribou 有史以来最好的测试用例 @user1965283:不是真的——现在它会在 Caribou 指出的那条线上崩溃。 在 runner = new Node() 之后,runner 永远不会为 NULL。 @user1965283 Pukku 值得感谢 - 他在我面前看到了这个问题【参考方案2】:

这里的逻辑是错误的

int location = ((unsigned)num) % size;
Node *runner = table[location];

if(runner == NULL ) // if null u dereference it!

 runner->num = num;

else

  while(runner != NULL )   // u loop until null
    runner = runner->next;
  
  runner->num = num;  // once u reach null u dereference it!

我会建议:

首先为您的节点创建ctor

class Node 
public:
  int num;
  Node * next;

  Node( int _n ) : num(_n), next(NULL)   
;

然后

if ( runner != NULL )

   while ( runner->next != NULL )
   
      runner = runner->next;
   
   runner->next = new Node( num );

else

  table[location] = new Node( num ); 

【讨论】:

【参考方案3】:

这段代码肯定行不通:

if(runner == NULL )
runner->num = num;

如果 runner 是 NULL,那么你永远不应该取消引用它(使用 * 或 -> 在它上面)。

【讨论】:

【参考方案4】:
Node *runner = table[location];
runner = runner->next;
if(runner == NULL )

您从未验证过table[location] 是否为空。但是在构建哈希表期间,节点表内没有节点(您将每个条目都设置为 null)。

您的代码的问题是您从不考虑分配节点。你应该这样做

Node* toInsert = new Node;
toInsert->next= NULL;
toInsert->num = num;

if(table[location]==NULL)
   table[location] = toInsert;  

else
    Node *runner = table[location];
    while(runner->next != NULL)
         runner = runner->next;
    
    runner->next = toInsert;

【讨论】:

以上是关于哈希表 - 链表数组 - C++的主要内容,如果未能解决你的问题,请参考以下文章

C++ 有没有结合了数组和链表优点的容器?

哈希表和链表的 C++ 访问冲突

为啥哈希表在存储桶的数组上使用链表?

在 C 中寻找数组(与链表)哈希表实现

数组链表哈希表

哈希表及其应用分析