【问题标题】:Make a hash table using smart pointers?使用智能指针制作哈希表?
【发布时间】:2017-08-27 16:01:01
【问题描述】:

我正在尝试使用智能指针创建一个哈希表,但我不确定我是否做得对。我一直在尝试使用它们的两种组合,但恐怕我不知道如何将表格初始化为空?也许这是错误的措辞,但我被困住了,我需要指出正确的方向。

我的哈希节点:

struct{
    hashNode(int k, std::string i) : key(k), item(i){};

    int key;
    std::string item;
}

我的哈希表:

class Hashtable
{
public:

    Hashtable(); //not sure how to build the constructor build an empty table.

    int hashFunction(int key);
    int find(int key);
    void insert(int key, std::string item);
    void remove(int key);

private:

    int tableSize = 10;
    std::shared_ptr<std::shared_ptr<hashNode>> hashTable;
    //std::vector<std::shared_ptr<hashNode>> hashTable;
};

我被困在这里,因为我不知道我是否正确实现了我的哈希表。或者,如果这只是一个坏主意。任何建议都可以。

【问题讨论】:

  • std::shared_ptr&lt;std::shared_ptr&lt;hashNode&gt;&gt; 你肯定不想这样。
  • 小心共享指针。除非您确实拥有拥有多个所有者的对象,否则它们很少是您想要的。如果只有一个用户负责删除指针,您需要std::unique_ptr
  • 好的,假设我正在尝试复制hashNode **hashtable,就像我在其他示例中看到的那样。这不是一回事吗?我想这就是我感到困惑的地方。实现向量是否更正确? @GuillaumeRacicot
  • 如果你做对了,根本不需要指针。您只需要一个向量向量 (std::vector&lt;std::vector&lt;hashNode&gt;&gt;)。
  • @Sailanarmo 唯一指针更好,但在指向数组时有不同的语法。共享指针不支持数组。请参阅文档。

标签: c++ vector hashtable smart-pointers


【解决方案1】:

带有容器的 HashTable 示例

class Hashtable
{
public:
    Hashtable(): hashTable(10) // initial size set here
    {
        // does nothing
    }
    int hashFunction(int key);
    int find(int key);
    void insert(int key, std::string item); // this gets a bit more complicated
                                            // due to copying during rehash
    void remove(int key);

private:
    std::vector<std::vector<hashNode>> hashTable; // vector knows its size 
};

这会使重新散列稍微复杂化,因为现在您必须复制而不是移动指针,但从好的方面来说,复制包含 unique_ptr 的内容时内存管理问题或困难为零。如果你复制它,它不会是独一无二的,不是吗?

【讨论】:

    【解决方案2】:

    使用std::unique_ptr 将您的hashNode 属性成员更改为单个指针。然后,在 HashTable 的构造函数中,您可以使用std::make_unique 对其进行初始化。

    在你HashTable.h

    class Hashtable {
    public:
       Hashtable(); 
    
       int hashFunction(int key);
       int find(int key);
       void insert(int key, std::string item);
       void remove(int key);
    
    private:
       int tableSize = 10;
       std::unique_ptr<hashNode[]> hashTable;  // As stated in the comments.
    };
    

    在您的 HashTable.cpp

    Hashtable::Hashtable() {
       hashTable = std::make_unique<hashNode[10]>();
    }
    

    【讨论】:

    • 我想我需要进一步查看文档,因为我已经简要介绍了智能指针并且只在 Trees 中使用过它们。但是这两者有什么区别呢?
    • 如果 tableSize 不是常量,make_unique&lt;hashNode[tableSize]&gt; 应该是不合法的。
    • @immibis,如果它只是要制作大小为 10 的初始表,我是否应该将其设为常量?当它半满时我会重新散列它,所以为了重新散列,我将它保留为一个非常数。但是当我创建一个新表时,表大小会变为 20。那这不是问题吗?
    • 两点:1)如果数组是固定大小的,为什么还要麻烦动态分配呢? 2) 考虑使用成员初始化器列表。如果您要做的第一件事是为它分配一个值,则可以节省几个周期将 unique_ptr 初始化为 null。
    • 好的。第 1 点被淘汰。
    猜你喜欢
    • 1970-01-01
    • 2012-07-08
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多