插入实施'Linear Hashing'

Insertion with implementing 'Linear Hashing'

本文关键字:Hashing Linear 插入      更新时间:2023-10-16

我必须为我的算法课程实现数据结构'线性哈希',但我遇到了一些问题。我已经直接实现了添加功能。我必须使用以下hashfunction:

h(x)= x mod 2^d

我的测试值是:

24200,16448,16432,4044,24546,10556,29009,25270,32579,13047

当我将此值添加到数据结构中时,我会得到以下内容:

LinearHashing [ TableSize=4 BucketSize=2 d=2 nextToSplit=0 ]
Elemente
values=
Bucket[0]
 [24200]  [16448]
Overflow Bucket:
 [16432]  [4044]
 [24546]  [10556]
 [25270]  [0]
Bucket[1]
 [29009]  [0]
Bucket[2]
 [0]  [0]
Bucket[3]
 [32579]  [13047]

但是" 25270"的值最终置于错误的桶中,我已经重新检查了一千次,我找不到我的错误。当我将OverflowBucketSize设置为" N/2"时,该错误已修复,但这可能只是一个巧合。该示例应该看起来像这样(如果我正确的算法):

LinearHashing [ TableSize=4 BucketSize=2 d=2 nextToSplit=0 ]
Elemente
values=
Bucket[0]
 [24200]  [16448]
Overflow Bucket:
 [16432]  [4044]
 [24546]  [10556]
 [0]  [0]
Bucket[1]
 [29009]  [0]
Bucket[2]
 [25270]  [0]
Bucket[3]
 [32579]  [13047]

我必须使用此测试程序测试我的数据结构:

http://pastebin.com/k1p4z6e3

我的数据结构必须基于我的教授提供的 *.h文件:

http://pastebin.com/79jleruf

这是我的完整代码:

http://pastebin.com/mw09uezx

最重要的功能是以下内容。我的添加功能:

template <typename E, size_t N>
void LinearHashing<E,N>::add(const E e[], size_t len) {
    for(size_t i=0; i < len; ++i){
        size_t address = compIndex(e[i]);
        for(size_t j=0; j < N; ++j){
            if(table[address].bucketstatus[j] == leer){
                table[address].bucketElem[j] = e[i];
                table[address].bucketstatus[j] = besetzt;
                break;
            }else if(j == (N-1) && table[address].newoverflow == nullptr){
                table[address].newoverflow = new OverflowContainer();
                addToOverflow(e[i],table[address].newoverflow);
                split();
                reHash(nts);
                if(nts+1 == (pow(2, d))){
                    nts=0;
                    ++d;
                }else{
                    ++nts;
                }
            }else if(j == (N-1) && table[address].newoverflow != nullptr){
                addToOverflow(e[i],table[address].newoverflow);
            }
        }
    }
}

用以下两个函数计算元素的索引:

hashvalue:

template <typename E> inline size_t hashValue(const E& e) { return size_t(e); }

compindex:

template <typename E, size_t N>
inline size_t LinearHashing<E, N>::compIndex(E e){
    size_t adrOP = powl(2,d);
    return hashValue(e) % adrOP;
}

通过以下功能添加溢出:

template <typename E, size_t N>
void LinearHashing<E, N>::addToOverflow(E e, LinearHashing::OverflowContainer *container) {
    size_t i=0;
    while( i < N/2){
        if(container->overflowstatus[i] == leer){
            container->overflowbucket[i] = e;
            container->overflowstatus[i] = besetzt;
            break;
        }else if(i == (N/2)-1 && container->nextOverflow == nullptr){
            container->nextOverflow = new OverflowContainer();
            container = container->nextOverflow;
            split();
            reHash(nts);
            if(nts+1 == (pow(2, d))){
                nts=0;
                ++d;
            }else{
                ++nts;
            }
            i=0;
        }else if(i == (N/2)-1 && container->nextOverflow != nullptr){
            container = container->nextOverflow;
            i=0;
        }else{
            ++i;
        }
    }
}

执行分裂我使用此功能:

template <typename E, size_t N>
void LinearHashing<E,N>::split(){
    Bucket* tmp = new Bucket[size()+1];
    std::copy(table,table+size(),tmp);
    delete[] table;
    table = tmp;
    ++n;
}

现在,当创建新溢出时,我执行拆分,以重新重新启动nexttosplit行,我使用以下重新命令:

template <typename E, size_t N>
void LinearHashing<E, N>::reHash(size_t index){
    bool reHashed = false;
    for(size_t i = 0; i < N; ++i){
        if(compIndex(table[index].bucketElem[i]) != compReIndex(table[index].bucketElem[i]) && table[index].bucketstatus[i] == besetzt){
            for (size_t j = 0; j < N && !reHashed ; ++j) {
                if(table[n-1].bucketstatus[j] == leer){
                    table[n-1].bucketElem[j] = table[index].bucketElem[i];
                    table[n-1].bucketstatus[j] = besetzt;
                    table[index].bucketstatus[i] = leer;
                    table[index].bucketElem[i] = 0;
                    reHashed = true;
                }
            }
            reHashed = false;
        }
    }
    if(table[index].newoverflow != nullptr){
        reHashOverflow(table[index].newoverflow);
    }
}
template <typename E, size_t N>
void LinearHashing<E, N>::reHashOverflow(OverflowContainer* container) {
    size_t i=0;
    bool reHashed = false;
    while(i < (N/2)){
        if(compIndex(container->overflowbucket[i]) != compReIndex(container->overflowbucket[i]) && container->overflowstatus[i] == besetzt){
            for(size_t j=0; j < N && !reHashed; ++j){
                if(table[n-1].bucketstatus[j] == leer){
                    table[n-1].bucketElem[j] = container->overflowbucket[i];
                    table[n-1].bucketstatus[j] = besetzt;
                    container->overflowbucket[i] = 0;
                    container->overflowstatus[i] = leer;
                    reHashed = true;
                }else if(j == N-1 && table[n-1].newoverflow == nullptr){
                    table[n-1].newoverflow = new OverflowContainer();
                    addToOverflow(container->overflowbucket[i],table[n-1].newoverflow);
                    container->overflowbucket[i] = 0;
                    container->overflowstatus[i] = leer;
                    reHashed = true;
                }else if(j == N-1 && table[n-1].newoverflow != nullptr){
                    addToOverflow(container->overflowbucket[i], table[n-1].newoverflow);
                    container->overflowbucket[i] = 0;
                    container->overflowstatus[i] = leer;
                    reHashed = true;
                }
            }
            reHashed = false;
            ++i;
        }else{
            ++i;
        }
        if(container->nextOverflow){
            container = container->nextOverflow;
            i = 0;
        }
    }
}

我现在已经完全重新完成了它,并发现了很多错误,例如拆分和重新函数的隐式递归。