最简单易懂的hash表实现代码

//构造hash算法:
//1.直接定址法 H(key) = key 或者 H(key) = a*key + b;
//2.数字分析法
//3.平方取中法: 将数据key进行平方,根据情况随意取数据的中间几位即可
//4.折叠法: 将数据分割成位数较小的几分,然后将几份数据进行叠加。456 789 12 ——>456 789 120 以上三者相加
//5.除留余数法: H(key) = key MOD p, p<=N (N为表长)
//6.随机数法: H(key) = random(key) random为随机函数

//key1 != key2 —> H(key1) == H(key2),称之为冲突

//解决冲突的方法:
//1.开放定址法 H(key) = ( H(key)+di ) MOD m i=1,2,3…k(k<=m-1)
//a.di = 1,2,3,…m-1,称为线性探测再散列
//b.di = 1*1 ,-1*1,2*2, -2*2…-k*k (k<=m/2),称之为二次探测再散列
//c.di = 伪随机数序列, 称之 伪随机探测再散列

//2.再hash法 Hi = RH(key) i = 1,2,3,…,k
//3.链地址法
//4.建立公共溢出区

实例一

//////////////////////////////hash表实现例子////////////////////////////////////////////
//////////////////表长为N,采用除留余数法构造hash算法,开放地址法解决冲突///////////////
#include <stdio.h>
#define N 4

typedef int datatype;
typedef struct
{
    datatype key;
}HashTable;

int Hashsearch(HashTable *HT, datatype k)
{
    int addr,i=0;
    addr = k % N;//除留余数法:H(key) = key MOD p,p<=N   (N为表长)

    while(i<N && HT[addr].key != -1 && HT[addr].key != k)
    {
        i++;
        addr = (addr+1)%N;      //产生冲突,采用开放地址法中的线性探测再散列
    }
    if(i == N)
        return -1;  //表溢出
    else
    {

        return addr;//插入地址 下标
    }

}

int HashInsert(HashTable *HT, datatype R)
{

    int addr;
    addr = Hashsearch(HT, R);//找到要插入的位置:不产生冲突

    //如果hash表的数据溢出-1,或者表中的数据与要插入的数据一致,返回
    //否则,直接插入数据
    if(addr==-1 || HT[addr].key == R)
    {
        return 1;
    }
    else
    {
        HT[addr].key = R;
        printf("%d ",HT[addr].key);
        return 0;
    }
}

int main()
{
    HashTable HT[N];//hash表,长度为N

    for(int i=0;i<N;i++)//初始化hash表,表中数据
        HT[i].key = -1;

    for(int i=0;i<20;i++)//数据插入到hash表
    {
        int value = HashInsert(HT,i+200);
        if(value)
            printf("表溢出或记录已存在!\n");
        else
        {
            printf("插入成功!\n");
        }
    }

    //打印hash表
    for(int i=0;i<N;i++)
    {
        printf("%d ",HT[i].key);
    }
    printf("\n");

    getchar();
    return 0;
}

实例二

//散列表查找算法(Hash) 
#include <stdio.h> 
#include <stdlib.h> 
#define OK 1 
#define ERROR 0 
#define TRUE 1 
#define FALSE 0 
#define SUCCESS 1 
#define UNSUCCESS 0 
#define HASHSIZE 7 
#define NULLKEY -32768 
typedef int Status; 
typedef struct 
{ 
    int *elem; //基址 
    int count; //当前数据元素个数 
}HashTable; 
int m=0; // 散列表表长

/*初始化*/ 
Status Init(HashTable *hashTable) 
{
    int i;
    m=HASHSIZE;
    hashTable->elem = (int *)malloc(m * sizeof(int)); //申请内存 
    hashTable->count=m; 
    for (i=0;i<m;i++) 
    { 
        hashTable->elem[i]=NULLKEY;
    } 
    return OK;
}

/*哈希函数(除留余数法)*/ 
int Hash(int data)
{ 
    return data % m; 
}

/*插入*/
void Insert(HashTable *hashTable,int data) 
{ 
    int hashAddress=Hash(data); //求哈希地址 //发生冲突 
    while(hashTable->elem[hashAddress]!=NULLKEY) 
    { //利用开放定址的线性探测法解决冲突 
        hashAddress=(++hashAddress)%m; 
    } //插入值 
    hashTable->elem[hashAddress]=data;
} 

/*查找*/ 
int Search(HashTable *hashTable,int data) 
{ 
    int hashAddress=Hash(data); //求哈希地址 //发生冲突 
    while(hashTable->elem[hashAddress]!=data) 
    { //利用开放定址的线性探测法解决冲突 
        hashAddress=(++hashAddress)%m; 
        if (hashTable->elem[hashAddress]==NULLKEY||hashAddress==Hash(data)) 
            return -1;
    } //查找成功 
    return hashAddress; 
}

/*打印结果*/ 
void Display(HashTable *hashTable) 
{ 
    int i;
    printf("\n//==============================//\n"); 
    for (i=0;i<hashTable->count;i++) 
    { 
        printf("%d ",hashTable->elem[i]); 
    }
    printf("\n//==============================//\n"); 
}

int main() 
{ 
    int i,j,result;
    HashTable hashTable; 
    int arr[HASHSIZE]={28,29,28,28,26,30,38};
    printf("***************Hash哈希算法***************\n"); 

    //初始化哈希表 
    Init(&hashTable);
    Display(&hashTable);

    //插入数据 
    for (i=0;i<HASHSIZE;i++)
    { 
        Insert(&hashTable,arr[i]); 
    } 
    Display(&hashTable);

    //查找数据 
    result= Search(&hashTable,89); 
    if (result==-1)
        printf("对不起,没有找到!\n"); 
    else 
        printf("89在哈希表中的位置是:%d\n",result);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值