为什么我的变量值随机变化?

我是C编程的新手,我最近才开始学习数据结构和算法.我选择的教科书是C中的数据结构和算法分析,它引入了第5章中的哈希表ADT.这里是其四开放寻址版本的一个实现,其中函数Find将Key和TableSize的值传递给Hash函数,它将散列值作为变量CurrentPos返回.以下是函数Hash和Find:

Index
Hash( ElementType Key, int TableSize )
{
    return Key % TableSize;
}

Position
Find(ElementType Key, HashTable H)
{
    Position CurrentPos;
    int CollisionNum;

    CollisionNum = 0;
    CurrentPos = Hash(Key, H->TableSize);
    while(H->TheCells[CurrentPos].Info != Empty && H->TheCells[CurrentPos].Element != Key)
    {
        CurrentPos += 2 * ++CollisionNum - 1;
        if(CurrentPos >= H->TableSize)
            CurrentPos -= H->TableSize;
    }
    return CurrentPos;
}

这是标题:

    typedef int ElementType;
    #ifndef _HashQuad_H
    #define _HashQuad_H

    typedef unsigned int Index;
    typedef Index Position;

    struct HashTbl;
    typedef struct HashTbl *HashTable;

    HashTable InitializeTable( int TableSize );
    void DestroyTable( HashTable H );
    Position Find( ElementType Key, HashTable H );
    void Insert( ElementType Key, HashTable H );
    ElementType Retrieve( Position P, HashTable H );
    HashTable Rehash( HashTable H );

    #endif 

以下是源文件中的typedef和结构:

    struct HashEntry
    {
        ElementType      Element;
        enum KindOfEntry Info;
    };

    typedef struct HashEntry Cell;

    /* Cell *TheCells will be an array of */
    /* HashEntry cells, allocated later */
    struct HashTbl
    {
        int TableSize;
        Cell *TheCells;
    };

这是H被初始化的方式

    HashTable
    InitializeTable( int TableSize )
    {
        HashTable H;
        int i;

    if( TableSize < MinTableSize )
        {
            Error( "Table size too small" );
            return NULL;
        }

        /* Allocate table */
        H = malloc( sizeof( struct HashTbl ) );
        if( H == NULL )
            FatalError( "Out of space!!!" );

        H->TableSize = NextPrime( TableSize );

        /* Allocate array of Cells */
        H->TheCells = malloc( sizeof( Cell ) * H->TableSize );
        if( H->TheCells == NULL )
            FatalError( "Out of space!!!" );

        for( i = 0; i < H->TableSize; i++ )
            H->TheCells[ i ].Info = Empty;

        return H;
    }

现在问题是,但是这种实现在大多数情况下都能正常工作.它有时会遇到崩溃.当它发生时,我尝试单元测试并发现在一定轮次调用Hash函数后,CurrentPos的值将被指定为一个比Hash函数的实际返回值大得多的整数,它可能是1000加上甚至更大.
例如,如果Key为29918且TableSize为101,则正确答案和是Hash返回的值为22,但在分配行之后:

 CurrentPos = Hash(Key, H->TableSize);

无论如何,CurrentPos的值本身都变为1580.
请注意,基于函数time()的种子使用rand()随机分配的Key值小于integer类型的上边界 – 我的意思是应该没有溢出.

我努力寻找手表,但没有其他错误或线索.我很困惑,因为这个错误实际上是随机发生的.有没有人熟悉这个?

最佳答案 如果CollisionNum变得足够大,那么此测试将无法正常工作:

       if(CurrentPos >= H->TableSize)
            CurrentPos -= H->TableSize;

因为如果CurrentPos> = H-> TableSize * 2,则在减去H-> TableSize之后,CurrentPos仍将超出范围.

您应该将此更改为:

       while (CurrentPos >= H->TableSize)
            CurrentPos -= H->TableSize;

要么:

       CurrentPos = CurrentPos % H->TableSize;

甚至:

       CurrentPos %= H->TableSize;
点赞