【问题标题】:C++ HashTable Quadratic Probing Insert method with resize not working?调整大小的 C++ HashTable 二次探测插入方法不起作用?
【发布时间】:2021-02-25 02:27:36
【问题描述】:

一旦阈值超过预定量 0.65,此方法应该调整数组的大小。 问题是在调整大小后,析构函数会删除包含所有新复制信息的数组。我不知道如何解决它。

那里的一些 cmet 只是我在头脑风暴可能是什么问题。


void Hashtable::insert(int value)
{
    int i = 0;
    int key = hash(value);  // hash(value) % N?

    //check load factor to see if it needs to be resized               
    double q = ((double)(currsize+1) / (double)currcapacity); //calculate current threshold

    if ( q >= threshhold) { //if current threshold is >= to 0.65


        int newSize = nextPrime(currcapacity * 2);  //get new size at the next prime number

        Hashtable newtable(newSize); //create a new table; HOW DO I CREATE THIS ON THE HEAP?

    
        for (int j = 0; j < currcapacity; j++) {  //runs through table calling insert to insert new items into table
            if (htable[j] != EmptyBeforeStart && htable[j] != EmptyAfterRemoval) {
                newtable.insert(htable[j]);
            }
        }

        delete[] htable; //delete old table
        
        this->htable = newtable.htable; //re-assign address of htbale to be newtable.htable //THIS ASSINGMENTS GETS DELETED BY THE DESTRUCTOR
        this->currcapacity = newSize; //update capacity

        this->insert(value);   

        //THE PROBLEM IS THAT THE DESTRUCTOR GETS CALLED AND DELETES THE htable BECAUSE THE NEWTABLE HTABLE WAS DECLARED AUTOMAITCALLY NOT ON THE HEAP.
        
    }
    else {

        while (i < currcapacity) {
            if (htable[key] == EmptyBeforeStart || htable[key] == EmptyAfterRemoval) {
                htable[key] = value;
                currsize++;
                return;
            }
            i++;
            key = (hash(value) + 0 * i + 1 * i * i) % (int)currcapacity;
        }
    }
}

【问题讨论】:

    标签: c++ hashtable probing linear-probing quadratic-probing


    【解决方案1】:

    你的析构函数被调用是因为你在堆栈上用这一行创建了一个Hashtable对象:

    Hashtable newtable(newSize);
    

    这创建了一个临时表,您填充了该表,然后在函数返回之前将其丢弃(销毁)。但在那之前,你偷走了它的指针并将它存储在当前的哈希表中。这是个大问题,因为当 那个 表被销毁时,它会尝试删除一个已经被删除的指针。

    我想你的意思是:

    int *newtable = new int[newSize];
    std::fill(newtable, newtable + newSize, EmptyBeforeStart);
    

    但是,您需要更改将现有值复制到其中的重新散列部分。现在,我并不是说以下是一个很棒的设计,但无需重新设计任何其他内容,您就可以这样做:

    // Store information about current table before replacing it
    int *oldtable = htable;
    int oldcapacity = currcapacity;
    
    // Replace the hash table with new empty one
    htable = newtable;
    currcapacity = newSize;
    
    // Rehash old values
    for (int j = 0; j < oldcapacity ; j++) {
        if (oldtable[j] != EmptyBeforeStart && oldtable[j] != EmptyAfterRemoval) {
            insert(oldtable[j]);
        }
    }
    
    // Clean up
    delete[] oldtable;
    

    看看上面实际上是如何用新的空表替换表的,但保留一个指向旧数据的指针。然后它调用insert 将所有旧值散列到新表中。然后当它完成时,可以释放旧内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-27
      • 2015-05-13
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 2016-05-28
      • 2022-11-06
      • 2015-10-22
      相关资源
      最近更新 更多