散列 - 开放定址散列

散列 - 开放定址散列

开放定址散列法是另一种不用链表解决冲突的方法
不过, 在开放定址散列标准的删除方法不能使用

而大致的算法思路跟其散列-分离链表法类似

//enum 中 L, M, Delede代表链表的三种状态
struct ListNode;
struct HashTbl;
typedef struct ListNode *Position;
typedef struct HashTbl *HashTabl;
const int N = 10;

enum Kind { L, M, Deleted };

struct ListNode
{
    char *ch;
    enum Kind Enum;
};

struct HashTbl
{
    int The_SIZE;
    Position *The_ListNode;
};

其他的插入都是一样的思路, 这里讲解的是, 两个初始化

程序开始时的基本初始化


//初始化
HashTabl Creat(int SIZE)
{
    HashTabl H;
    H = (HashTabl)malloc(sizeof(struct HashTbl));
    if (H == NULL)
        exit(0);

    H->The_SIZE = SIZE;

    H->The_ListNode = (Position *)malloc(sizeof(Position));
    if (H->The_ListNode == NULL)
        exit(0);

    //状态 M = 1 ,表示初始化化过
    for (int i = 0; i < SIZE; i++)
        H->The_ListNode[i]->Enum = M;

    return H;
}

以及扩大数组的后续初始化

//当初始化的数组被占据很多的时候, 
//我们需要重新开辟一个更大的数组范围, 并将之前保存的数据拷贝过来
void ReHash(HashTabl &H)
{
    int ReSIZE;
    Position *P;
    ReSIZE = H->The_SIZE;
    P = H->The_ListNode;

    H = Creat(2 * ReSIZE);

    for (int i = 0; i < ReSIZE; i++)
        if (P[i]->Enum == L)
            Inset(H, P[i]->ch);
}

源代码


#include <stdio.h>
#include <stdlib.h>

struct ListNode;
struct HashTbl;
typedef struct ListNode *Position;
typedef struct HashTbl *HashTabl;
const int N = 10;

//enum 中 L, M, Delede代表链表的三种状态
enum Kind { L, M, Deleted };

struct ListNode
{
    char *ch;
    enum Kind Enum;
};

struct HashTbl
{
    int The_SIZE;
    Position *The_ListNode;
};

//字符串转换数字
unsigned int Hash(char *key, int SIZE)
{
    unsigned int HashSIZE = 0;

    while (*key != '\0')
        HashSIZE = (HashSIZE << 5) + *key++;

    return HashSIZE % SIZE;
}

//初始化
HashTabl Creat(int SIZE)
{
    HashTabl H;
    H = (HashTabl)malloc(sizeof(struct HashTbl));
    if (H == NULL)
        exit(0);

    H->The_SIZE = SIZE;

    H->The_ListNode = (Position *)malloc(sizeof(Position));
    if (H->The_ListNode == NULL)
        exit(0);

    //状态 M = 1 ,表示初始化化过
    for (int i = 0; i < SIZE; i++)
        H->The_ListNode[i]->Enum = M;

    return H;
}

//查找
unsigned int Find(char *key, HashTabl H)
{
    unsigned int NUM;
    int num; num = 0;

    //找到对应的钥匙
    NUM = Hash(key, H->The_SIZE);

    // != M 代表没有被初始化, 即数组结束
    while (H->The_ListNode[NUM]->Enum != M && H->The_ListNode[NUM]->ch != key)
    {
        NUM = NUM + 2 * (++num) - 1;
        if (NUM >= H->The_SIZE)
            NUM -= H->The_SIZE;
    }

    //返回对应数组角标
    return NUM;
}

//插入
void Inset(HashTabl H, char *key)
{
    unsigned int NUM;
    NUM = Hash(key, H->The_SIZE);

    while (H->The_ListNode[NUM]->Enum != L)
    {
        H->The_ListNode[NUM]->Enum = L;
        H->The_ListNode[NUM]->ch = key;
    }
}

//当初始化的数组被占据很多的时候, 
//我们需要重新开辟一个更大的数组范围, 并将之前保存的数据拷贝过来
void ReHash(HashTabl &H)
{
    int ReSIZE;
    Position *P;
    ReSIZE = H->The_SIZE;
    P = H->The_ListNode;

    H = Creat(2 * ReSIZE);

    for (int i = 0; i < ReSIZE; i++)
        if (P[i]->Enum == L)
            Inset(H, P[i]->ch);
}

int main()
{


    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值