简体   繁体   English

哈希表实现调整大小功能

[英]Hash Table implementing Resize function

I've been given an assignment to adjust a hash table implementation to allow for dynamic resizing. 我被分配了一个调整哈希表实现以允许动态调整大小的任务。 While I've looked around for clues and info, I'm still confused as to how hash tables behave and therefore how I should go about with the resize. 虽然我一直在寻找线索和信息,但是我仍然对哈希表的行为以及如何调整大小感到困惑。 I was told I need to add a resize function, call it in insert and modify the constructor. 有人告诉我我需要添加一个调整大小的函数,在insert中调用它并修改构造函数。 I think I've done right with the insert, seems simple enough, but the resize itself and the constructor are what I'm struggling with. 我认为我已经正确完成了插入操作,看起来似乎很简单,但是调整大小本身和构造函数是我一直在努力的目标。

EDIT: So I've worked on the resize function, insert and constructor but I'm getting an error at the for loop in resize() to insert old data into the larger table, and I'm not sure what is going wrong now. 编辑:所以我已经在调整大小函数,插入和构造函数上工作,但我在resize()的for循环中遇到了一个错误,即将旧数据插入到更大的表中,而且我不确定现在出了什么问题。 Any ideas? 有任何想法吗?

Here is the header: 这是标题:

#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib>    // Provides size_t
#include <cassert>  // Provides assert

namespace main_savitch_12A
{
template <class RecordType>
class table
{
public:
size_t CAPACITY; 
    // CONSTRUCTOR
    table( );
    // MODIFICATION MEMBER FUNCTIONS
    void insert(const RecordType& entry);
    void remove(int key);
void resize( );
    // CONSTANT MEMBER FUNCTIONS
    bool is_present(int key) const;
    void find(int key, bool& found, RecordType& result) const;
    size_t size( ) const { return used; }
private:
    // MEMBER CONSTANTS -- These are used in the key field of special records.
    enum { NEVER_USED = -1 };
    enum { PREVIOUSLY_USED = -2 };
    // MEMBER VARIABLES
    RecordType *data; //[CAPACITY];
    size_t used;
    // HELPER FUNCTIONS
    size_t hash(int key) const;
    size_t next_index(size_t index) const;
    void find_index(int key, bool& found, size_t& index) const;
    bool never_used(size_t index) const;
    bool is_vacant(size_t index) const;
};

constructor implementation: 构造函数实现:

template <class RecordType>
table<RecordType>::table( )
{
    CAPACITY = 30;
    data = new RecordType[CAPACITY];

size_t i;

used = 0;
for (i = 0; i < CAPACITY; ++i)
    data[i].key = NEVER_USED;

}

resize implementation: 调整大小的实现:

template <class RecordType>
void table<RecordType>::resize( )
{

    RecordType *oldData = data;
    int oldSize = CAPACITY;
    CAPACITY *= CAPACITY;

    //create a new table
    RecordType *newData;
    newData = new RecordType[CAPACITY];

    size_t i;
    used = 0;
    for (i = 0; i < CAPACITY; i++)
        newData[i].key = NEVER_USED;

    //place data from old table to new, larger table.
    for (int i = 0; i < oldSize; i++)
    {
        insert(newData[hash(i)]); //this is where I'm having trouble.
    }

    data = newData;
    delete[] oldData;
}

insert implementation: 插入实现:

template <class RecordType>
void table<RecordType>::insert(const RecordType& entry)
// Library facilities used: cassert
{
    bool already_present;   // True if entry.key is already in the table
    size_t index;        // data[index] is location for the new entry

    assert(entry.key >= 0);

    // Set index so that data[index] is the spot to place the new entry.
    find_index(entry.key, already_present, index);

    // If the key wasn't already there, then find the location for the new entry.
    if (!already_present)
    {
        if (size( ) >= CAPACITY)
        {
            resize( ); // resize the table.

            insert(entry); // reinsert entry into new table.
        }
        else if (size( ) < CAPACITY)
        {
            index = hash(entry.key);

            while (!is_vacant(index))
                index = next_index(index);
            ++used;
        }
    }

    data[index] = entry;
    size_t i;
    for (i=0; i<CAPACITY; i++) cout << data[i].key << ' ';
    cout << endl;
}

Thanks for the help! 谢谢您的帮助!

Currently, data is a fixed size array. 当前, data是固定大小的数组。 You need a variable size storage 您需要可变大小的存储空间

RecordType data[CAPACITY];

So, data needs to be a pointer rather than a fixed array, and you need to dynamically allocate it in the constructor. 因此, data需要是指针而不是固定数组,并且需要在构造函数中动态分配数据。

Of course, also change CAPACITY from being a constant to a variable (per table, so not static - I would change it's name to something that doesn't look like a macro/constant too. 当然,也可以将CAPACITY从一个常量更改为一个变量(每个表,因此不是static -我会将其名称更改为看起来也不像宏/常量的名称。

This bit is "almost there": 这一点“几乎在那里”:

table *newT;
newT = new table(newSize);

The type should not be the hashtable, but RecordType . 该类型不应为哈希表,而应为RecordType

And, as the comment says, you need to transfer the current data to the new data, and then make the new table the current data. 而且,正如评论所述,您需要将当前数据传输到新数据,然后将新表作为当前数据。 Finally, delete the now old data. 最后,删除现在的旧数据。

Edit: I'm intentionally NOT writing the code for you. 编辑:我故意不为您编写代码。 Your task is to learn. 您的任务是学习。 I wrote dynamically resizeable hash-tables some 20-odd years back, and I don't think I need to practice it right now. 大约20年前,我写了可动态调整大小的哈希表,我认为我现在不需要练习它。 You are the one learning how to do it. 您是一个学习如何做的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM