【问题标题】:follow up on hash table c++ , this->next = NULL pointer跟进哈希表 c++,this->next = NULL 指针
【发布时间】:2017-07-25 18:55:25
【问题描述】:

这是对我提出的另一个问题的跟进,它是关于 this->next = NULL 指针在下面的 HashNode 构造函数中。 我的问题是,我不明白为什么 htable[hash_val]->next 不等于 NULL 而是实际上有一个内存地址,即使 this->next = NULL ,如构造函数中所写。

谁能告诉我为什么 htable[hash_val]->next 不等于 NULL 并且有一个与之关联的地址。找了一会儿好像没找到。我可以看到 htable[hash_val] 会有一个值,但我认为 htable[hash_val]->next 会是 NULL 。谢谢 。

#include<iostream>
using namespace std;
const int TABLE_SIZE = 128;

class HashNode
{
    public:
    int key;
    int value;
    HashNode* next;
    HashNode(int key, int value)
    {
        this->key = key;
        this->value = value;
        this->next = NULL; // shouldn't htable[hash_val]->next = NULL 
    }
};


class HashMap
{
    private:
    HashNode** htable;

    public:
    HashMap()
    {
        htable = new HashNode*[TABLE_SIZE];
        for (int i = 0; i < TABLE_SIZE; i++)
            htable[i] = NULL;
    }


    int HashFunc(int key)
    {
        return key % TABLE_SIZE;
    }

    /*
     * Insert Element at a key
     */
    void Insert(int key, int value)
    {
        int hash_val = HashFunc(key);
        HashNode* prev = NULL;
        HashNode* entry = htable[hash_val];

        while (entry != NULL)
        {
            prev = entry;
            entry = entry->next;
         }
        if (entry == NULL)
        {
            entry = new HashNode(key, value);

            if (prev == NULL)
        {
                htable[hash_val] = entry;
            }
        else
        {
                prev->next = entry;

            }
        }

    }
    void testnull(int key){
        int hash_val = HashFunc(key);
        cout<<htable[hash_val]->next;  // outputs an address , not NULL
    }
   int Search(int key)
       {
        bool flag = false;
        int hash_val = HashFunc(key);
        HashNode* entry = htable[hash_val];
        while (entry != NULL)
        {
            if (entry->key == key)
        {
                cout<<entry->value<<" ";
                flag = true;
            }
            entry = entry->next;
        }
        if (!flag)
            return -1;
        }
  };


int main() {

HashMap hash; 

hash.Insert(3,7);
hash.Insert(3,8);
hash.testnull(3);


// your code goes here
return 0;
}

【问题讨论】:

    标签: c++ pointers this hashtable


    【解决方案1】:

    您插入了两个具有相同键的元素。 您的类没有“等于”比较,因此每次添加新元素时,它都会被放入同一个口袋(相同的哈希码)但作为下一条记录(考虑到键不相等)。这就是为什么你有两个记录。第一个的下一条记录不为空。如果您添加具有相同键的新记录,它应该替换以前的记录,我最喜欢哈希映射实现。

    我会像这样更改代码:

            while (entry != NULL)
            {
                if(entry->key == key)
                {
                    entry->value = value;
                    return; 
                }
                prev = entry;
                entry = entry->next;
             }
    

    【讨论】:

    • 感谢您的回复,@Anthony D,这不是家庭作业,不知道离开 cmets 会成为家庭作业:),但无论如何,回到理解这一点。我看到您说为 value 参数添加 7 和 8,它会插入您所显示的这些值,并且 next “非常正常”获取值7 后 8 。
    • 也就是说,this->value 获取第一个值,this->next 获取第二个值,你是说?输入第三个值怎么样,哪个指针是左值?
    • "和下一个"相当正常"在 7 之后得到值 8"。这并不正确。如果您的哈希表大小为 4 ant,则您的密钥为 3 和 7,它们的哈希值均为 3 (3%4 == 7%4)。所以他们会进入同一个口袋,但进入列表中的不同位置。例如,3 在条目中,7 在条目中-> 下一个。具有相同的下一个唯一键进入 entry->next->next 等。一旦通过哈希获得记录,您应该在包含列表中搜索确切的键。如果您放置的两个值不仅具有相同的哈希值而且具有相同的键,它应该替换前一个值。在您的代码中缺少此比较。
    • 感谢 Vadim,我再次查看了代码,我想我知道我错过了什么。在带有 prev = entryInsert 函数中,prev 指针是(共享)entry 的地址,并且稍后在 Insert 函数中,prev->next=entryentry->next=entry 相同,因为两者都是 prev 和 entry 共享相同的地址。
    • Thx Vadim,您添加的代码对两个相同的键有很大帮助
    【解决方案2】:

    当然htable[hash_val]-&gt;next 不为NULL。您正在使用链表解决冲突。

    1) 最初:

    [0] -> NULL
     |
    ...
     |
    [3] -> NULL
     |
    ...
    

    2) 在键 3 处插入 7。

    [0] -> NULL
     |
    ...
     |
    [3] -> 7 -> NULL
     |
    ...
    

    3) 您在键 3 处插入 8(与 7 相同的键)。

    [0] -> NULL
     |
    ...
     |
    [3] -> 7 -> 8 -> NULL
     |
    ...
    

    7 的下一个是8 是很正常的,因为它们的键都是 3。因此,您的代码正在做它应该做的事情。

    PS :如果您理解,或者至少在开始做作业之前您的课堂课程,这将节省您(和我们)的时间(@ 987654327@ 送你)。在 Stack Overflow 上,只有在表明您确实试图找到问题的答案时,您才应该提出问题。毕竟 SO 是为了帮助专业人士、学生和其他人解决日常生活中的编程问题,而不是让别人帮你看你的作业! :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-18
      • 2014-05-22
      • 2011-06-10
      • 2020-07-23
      • 2021-12-01
      • 2011-04-09
      • 2012-07-08
      相关资源
      最近更新 更多