算法:开放定址法散列表

Posted jmst

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:开放定址法散列表相关的知识,希望对你有一定的参考价值。

hash.h

#ifndef _HASHQUAD_H
#define _HASHQUAD_H

#define MinTableSize 10

struct HashEntry;
struct HashNode;

typedef char *ElementType;
typedef unsigned int Index;
typedef Index Position;
typedef struct HashNode *HashTable;
typedef struct HashEntry *Cell;

enum KindOfEntry{Legitimate,Empty,Deleted};

HashTable InitializeHashTable(int TableSize);
void DestoryTable(HashTable H);
Position Find(ElementType key,HashTable H);
void Insert(ElementType key,HashTable H);
void Delete(ElementType key,HashTable H);
Index Hash(const char *key,int TableSize);
HashTable Rehash(HashTable H);

#endif

struct HashEntry
{
    ElementType key;
    KindOfEntry info;//此处为懒惰删除域 
};

struct HashNode
{
    int TableSize;
    Cell *TheCells;//执行Cell的指针数组 
};

hash.c

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

//生成下个素数 
static unsigned int NextPrime(int N)
{
    if(N%2==0)
        N++;
    for(;;N+=2){
        for(i=3;i*i<=N;i+=2){
            if(N%i==0){
                goto ContOuter;
            }
        }
        return N;
        ContOuter:;
    }
}
Index Hash(const char *key,int TableSize)
{
    unsigned int HashVal=0;
    while(*key!=\0){
        HashVal=(HashVal<<5)+*key++;
    }
    return HashVal%TableSize;
}
HashTable InitializeHashTable(int TableSize)
{
    HashTable H;
    H=(HashTable)malloc(sizeof(struct HashNode));
    if(H==NULL){
        printf("out of space");
        return NULL;
    }
    H->TableSize=NextPrime(TableSize);
    //分配地址空间
    H->TheCells=malloc(sizeof(Cell))*H->TableSize;
    if(H->TheCells==NULL){
        printf("out of space");
        return NULL;
    }
    for(i=0;i<H->TableSize;++i){
        H->TheCells[i]->info=Empty;
    }
    return H;
}
Position Find(ElementType key,HashTable H)
{
    Position CurrentPos;
    int CollisionNum=0;
    CurrentPos=Hash(key,H);
    while(H->TheCells[CurrentPos]->info!=Empty&&strcmp(H->TheCells[CurrentPos].info,key)!=0){
        //平方探测函数由  F(i) = F(i-1) + 2 * i - 1  
        CurrentPos+=2*++Collision-1;
        if(CurrentPos>TableSize){
            CurrentPos-=TableSize;
        }
    }
    return CurrentPos;
}
void Insert(ElementType key,HashTable H)
{
    Position Pos;
    Pos=Find(key,H);
    if(H->TheCells[Pos]->info!=Legitimate){
        H->TheCells[Pos]->info=Legitimate;
        H->TheCells[Pos]->key=malloc(strlen(key)+1);
        strcpy(H->TheCells[Pos]->key,key);
        H->TheCells[Pos]->key[strlen(key)]=\0;
    }
}
void Delete(ElementType key,HashTable H)
{
    Position Pos;
    Pos=Find(key,H);
    if(H->TheCells[Pos].info==Legitimate){
        H->TheCells[Pos].info=Legitimate;        
    }
}
void DestoryTable(HashTable H)
{
    free(H->TheCells);
    free(H);
}
HashTable Rehash(HashTable H)
{
    int i,OldSize;
    Cell *OldCells;
    OldCells=H->TheCells;
    OldSize=H->TableSize;
    H=IntializeHashTable(2*OldSize);
    //把原来表数据拷贝过来
    for(i=0;i<OldSize;++i){
        if(OldCells[i]->info==Legitimate){
            Insert(OldCells[i]->info,H);
        }
        free(OldCells);
    }
    return H;
}

 

以上是关于算法:开放定址法散列表的主要内容,如果未能解决你的问题,请参考以下文章

算法:分离链表法散列表

散列——排解冲突 开放定址法(上)

开放定址散列表

散列表的开放定址法以及再散列法(C语言)

算法小讲堂之哈希表|散列表|考研笔记

数据结构--开放定址法解决散列冲突时几种探测法的比较