数据结构——杂凑表(开放定址法)

本文介绍了一种使用开放定址法处理哈希表冲突的方法,包括线性探测再散列等策略,并提供了完整的C语言实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为产生冲突的地址Hash(key)求得一个地址序列:H0, H1, H2, …, Hk 1 <= k <= m-1其中:H0 = Hash(key),Hi = ( Hash(key) + di ) MOD m  (i=1, 2, …,k)
增量 di 有三种取法:
(1)线性探测再散列:di = 1, 2, 3, ... , m - 1
(2)平方探测再散列:di = 1^2, -1^2, 2^2, -2^2, …,
(3)伪随机探测再散列:di 是一组伪随机数列
注意:增量di应具有“完备性”,即产生的Hi均不相同,且所产生的k(m-1)个Hi值能覆盖哈希表中所有的地址。要求:
(1)平方探测时的表长m必为4j+3的质数;
(2)随机探测时的m和di没有公因子。

示例代码
HashTableMain.c
#include <stdio.h>
#include 
<stdlib.h>
#include 
"hash.h"

/*简单操作示例*/
int main(int argc, char **argv)
{
    
int p, c;
    HashTable 
*ht;
    
int a[N] = {47729111692228303789421};

    ht 
= (HashTable *)malloc(HASHSIZE * sizeof(HashTable));
    HashCreate(
&ht, a, N);
    printf(
"The number of elements : %d ", ht->count);
    HashSearch(
&ht, 2552&p, &c);
    printf(
"%d %d ", p, c);

    HashDelete(
&ht, 11);
    printf(
"The number of elements : %d ", ht->count);

    HashDestroy(
&ht);

    
return 0;
}

hash.h
#ifndef _HASH_H
#define _HASH_H

#define N 14
#define HASHSIZE 11
#define NIL -1

typedef 
int ElemType;
typedef 
struct Node{
    ElemType 
*elem;
    
int count;
}
HashTable;

int h(ElemType k);
int Increment(int i);
int Hash(ElemType k, int i);
int HashCreate(HashTable **ht, ElemType *a, int n);
void HashDestroy(HashTable **ht);
int HashSearch(HashTable **ht, ElemType k, int *p, int *c);
int HashInsert(HashTable **ht, ElemType k);
int HashDelete(HashTable **ht, ElemType k);

#endif

hash.c
#include <stdio.h>
#include 
<stdlib.h>
#include 
"hash.h"

int h(ElemType k)
{
    
return k % HASHSIZE;
}


/*用线性探查法求第i个增量di*/
int Increment(int i)
{
    
return i;
}


int Hash(ElemType k, int i)
{
    
return (h(k) + Increment(i)) % HASHSIZE;
}


int HashCreate(HashTable **ht, ElemType *a, int n)
{
    
int i;

    (
*ht)->elem = (ElemType *)malloc(HASHSIZE * sizeof(ElemType));
    
for(i = 0; i < HASHSIZE; i++)
        (
*ht)->elem[i]  = NIL;
    (
*ht)->count = 0;
    
for(i = 0; i < n; i++)
    
{
        HashInsert(
&(*ht), a[i]);
    }


    
return 1;
}


void HashDestroy(HashTable **ht)
{
    ElemType 
*p;

    p 
= (*ht)->elem;
    free(p);
    p 
= NULL;
    free(
*ht);
    (
*ht) = NULL;
}


/*
 *在开放定址哈希表ht中查找关键字值为k的元素
 *p指示插入位置,c计冲突数
 
*/

int HashSearch(HashTable **ht, ElemType k, int *p, int *c)
{
    
*= 0;
    
do
    
{
        
*= Hash(k, *c);
        
if((*ht)->elem[*p] == k)
            
return 1;
    }
while((*ht)->elem[*p] != NIL && ++*< HASHSIZE);

    printf(
"Not find %d ", k);

    
return 0;
}


int HashInsert(HashTable **ht, ElemType k)
{
    
int c, p;

    c 
= 0;
    
do{
        p 
= Hash(k, c);
        
if((*ht)->elem[c] == NIL)
        
{
            (
*ht)->elem[p] = k;
            (
*ht)->count++;
            
return p;
        }

    }
while(++< HASHSIZE);

    printf(
"Hash table overflow ");
    
return 0;
}


int HashDelete(HashTable **ht, ElemType k)
{
    
int p, c;

    
if(!(HashSearch(&(*ht), k, &p, &c)))
        
return 0;
    
else
    
{
        (
*ht)->elem[p] = NIL;
        (
*ht)->count--;

        
return 1;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值