线性探测法和平方探测法 - 哈希表 - 完整代码

直接上代码

#include <iostream>
#include <cmath>
using namespace std;
#define MAX 100000 //允许开辟的最大散列表长度
typedef int ElementType;
typedef int Index;      // 散列地址类型
typedef Index Position; // 数据所在的位置
typedef enum
{
    Legitimate, // 合法
    Empty,      // 空
    Deleted     // 已经删除
} EntryType;
typedef struct HashEntry Cell; // 散列单元类型
struct HashEntry
{
    ElementType Data;
    ElementType Info; //单元状态
};
typedef struct TblNode *HashTable; // 散列表类型
struct TblNode
{
    int TableSize; // 表的最大长度
    Cell *Cells;   // 存放数据的数组
};
// 返回一个大于N且不超过MAX的最小素数
int NextPrime(int N)
{
    // 从大于N的第一个奇数开始
    int p = (N % 2) ? N + 2 : N + 1;
    while (p <= MAX)
    {
        int i;
        for (i = (int)sqrt(p); i > 2; i--)
        {
            if (!(p % i))
                break; // 不是素数
        }
        if (i == 2)
            break;
        else
            p += 2;
    }
    return p;
}
HashTable CreateTable(int TableSize)
{
    HashTable H;
    H = (HashTable)malloc(sizeof(struct TblNode));
    // 保证散列表的最大长度是素数
    H->TableSize = NextPrime(TableSize);
    // 数组
    H->Cells = (Cell *)malloc(H->TableSize * sizeof(Cell));
    // 初始化数组为空单元
    for (int i = 0; i < H->TableSize; i++)
        H->Cells[i].Info = Empty;
    return H;
}
// 平方探测
Position Find(HashTable H, ElementType Key)
{
    Position Currentpos, NewPos;
    int CNum = 0; // 记录冲突次数
    // NewPos = Currentpos = Hash(Key, H->TableSize); // 初始散列的位置
    int p = H->TableSize;          // 应该是吧
    NewPos = Currentpos = Key % p; // 除留余数法

    // 为空的话就是找不到
    while (H->Cells[NewPos].Info != Empty && H->Cells[NewPos].Data != Key)
    {
        // 奇数次冲突 加i的平方
        if (++CNum % 2)
        {
            // CNum相当于i的映射
            // NewPos是增加后的位置
            NewPos = Currentpos + ((CNum + 1) / 2) * ((CNum + 1) / 2);
            // 如果加超了
            // 调增成合法的地址
            if (NewPos >= H->TableSize)
                NewPos = NewPos % H->TableSize;
        }
        else
        {
            NewPos = Currentpos - (CNum / 2) * (CNum / 2);
            while (NewPos < 0)
                NewPos += H->TableSize;
        }
    }
    /*
    // 开放地址法
    while (H->Cells[NewPos].Info != Empty && H->Cells[NewPos].Data != Key)
    {
        NewPos = (Currentpos + (++CNum)) % H->TableSize;
    }
    */
    // 此时NewPos 或者是Key的地址 或者是空单元地址
    return NewPos;
}
bool Insert(HashTable H, ElementType Key)
{
    Position Pos = Find(H, Key);

    if (H->Cells[Pos].Info != Legitimate)
    {
        H->Cells[Pos].Info = Legitimate;
        H->Cells[Pos].Data = Key;
        return true;
    }
    else
    {
        cout << "键值已存在\n";
        return false;
    }
}
bool Delete(HashTable H, ElementType Key)
{
    Position pos = Find(H, Key);
    if (H->Cells[pos].Info == Empty || H->Cells[pos].Info == Deleted)
        return false;
    else if (H->Cells[pos].Info == Legitimate)
    {
        H->Cells[pos].Info = Deleted;
        return true;
    }
    return true;
}

void PrintHashTable(HashTable H)
{
    for (int i = 0; i < H->TableSize; i++)
    {
        if (H->Cells[i].Info == Legitimate)
            cout << H->Cells[i].Data << ' ';
    }
    cout << "\n";
}
int main()
{
    HashTable htb;
    int N;
    cin >> N;
    htb = CreateTable(N);
    ElementType x;
    for (int i = 0; i < 5; i++)
    {
        cin >> x;
        Insert(htb, x);
    }
    PrintHashTable(htb);

    cin >> x;
    cout << Delete(htb, x) << endl;
    PrintHashTable(htb);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值