数据结构与算法分析-分离链接散列表的实现

#include<stdio.h>
#include<math.h>

typedef char* ElementType;
typedef unsigned int Index;
#define MinTableSize 15

struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;

HashTable InitializeTable(int TableSize);
void DestroyTable(HashTable H);
Position Find(ElementType key,HashTable H);
void Insert(ElementType key,HashTable H);
ElementType Retrieve(Position P);
void Delete(ElementType key,HashTable H);

struct ListNode
{
    ElementType Element;
    Position next;
};

typedef Position List;

struct HashTbl
{
    int TableSize;
    List *TheLists;
};

Index Hash(const char *key,int TableSize)
{
    unsigned int HashVal=0;
    while(*key!=‘\0‘)
    {
        HashVal+=*key++;
    }
    return HashVal%TableSize;
}

int NextPrime(int TableSize)
{
    int i,j=2;
    for(i=TableSize;i>0;i--)
    {
        while(j<sqrt(i))
        {
            if(i%j==0)
                break;
            j++;
        }
        if(j==sqrt(i))
            break;
    }
    return i;
}

HashTable InitializeTable(int TableSize)
{
    HashTable H;
    int i;
    if(TableSize<MinTableSize)
    {
        Error("Table size too small");
        return NULL;
    }
    H=malloc(sizeof(struct HashTbl));
    if(H==NULL)
    {
        FatalError("Out of space!!");
    }
    H->TableSize=NextPrime(TableSize);
    H->TheLists=malloc(sizeof(List)*H->TableSize);
    if(H->TheLists==NULL)
    {
        FatalError("Out of space!!");
    }
    for(i=0;i<H->TableSize;i++)
    {
        //分配头节点
        H->TheLists[i]=malloc(sizeof(struct ListNode));
        if(H->TheLists[i]==NULL)
            FatalError("Out of space!!");
        else
            H->TheLists[i]->next=NULL;
    }
    return H;
}

void DestroyTable(HashTable H)
{
    int i;
    for(i=0;i<H->TableSize;i++)
    {
        free(H->TheLists[i]);
    }
    free(H->TheLists);
    free(H);
}

Position Find(ElementType key,HashTable H)
{
    Position P;
    List L;
    L=H->TheLists[Hash(key,H->TableSize)];
    P=L->next;
    while(P!=NULL&&P->Element!=key)
        P=P->next;
    return P;
}

void Insert(ElementType key,HashTable H)
{
    Position Pos,NewCell;
    List L;
    Pos=Find(key,H);
    if(Pos==NULL)
    {
        NewCell=malloc(sizeof(struct ListNode));
        if(NewCell==NULL)
        {
            FatalError("Out of space!!");
        }
        else
        {
            L=H->TheLists[Hash(key,H->TableSize)];
            NewCell->next=L->next;
            NewCell->Element=key;
            L->next=NewCell;
        }
    }
}

ElementType Retrieve(Position P)
{
    if(P==NULL)
        return NULL;
    else
        return P->Element;
}

void Delete(ElementType key,HashTable H)
{
    Position Pos,Pre;
    List L;
    int i;
    Pos=Find(key,H);
    if(Pos==NULL)
        return;
    else
    {
        L=H->TheLists[Hash(key,H->TableSize)];
        for(Pre=L;pre->next!=NUll;Pre=Pre->next)
        {
            if(Pre->next==Pos)
            {
                free(Pos->Element);
                free(Pos);
                break;
            }
        }
    }
}

数据结构与算法分析-分离链接散列表的实现

时间: 2024-10-29 05:01:50

数据结构与算法分析-分离链接散列表的实现的相关文章

数据结构与算法分析-开放定址散列表的实现

#include<stdio.h> #include"fatal.h" typedef char* ElementType; typedef unsigned int Index; typedef Index Position; struct HashTbl; typedef struct HashTbl *HashTable; HashTable InitializeTable(int TableSize); void DestroyTable(HashTable H);

数据结构与算法——散列表类的C++实现(分离链接散列表)

散列表简介: 散列表的实现常被称为散列.散列是一种用于以常数平均时间执行插入.删除和查找的技术. 散列的基本思想: 理想的散列表数据结构只不过是一个包含一些项的具有固定大小的数组.(表的大小一般为素数) 设该数组的大小为TbaleSize,我们向该散列表中插入数据,首先我们将该数据用一个函数(散列函数)映射一个数值x(位于0到TbaleSize1-1之间):然后将该数据插入到散列表的第x的单元.(如果有多个数据映射到同一个数值,这个时候就会发生冲突) 散列函数介绍: 为了避免散列函数生成的值不是

数据结构---哈希表(散列表)

我们在Java容器中谈到:有哈希表(也称为散列表)支持的HashMap.LinkedHashSet等都具有非常高的查询效率.这其中就是Hash起的作用.顺序查找的时间复杂度为O(N) ,二分查找和查找树的时间复杂度为O(logN),而 哈希表的时间复杂度为O(1) .不过这只是理想状态,实际并不那么完美. 1.哈希表的概念和思想 哈希表是唯一的专用于集合的数据结构.可以以常量的平均时间实现插入.删除和查找. 哈希表的思想是:用一个与集合规模差不多大的数组来存储这个集合,将数据元素的关键字映射到数

数据结构(十二)散列表

定义 以下简称hahs 应用场景 适合查找与给定值相同的数据,不适合做范围查找,1对多映射查找 问题 冲突,散列表的理论依据是每个不同的关键字通过散列算法得到的结果都是唯一的,而现实中有可能出现几个结果相同的关键字. hash算法 构造一个散列算法考虑几个方面 直接定址法 按如下公式计算出关键字的hash值,当原始的key不重复,则得到的hash值就不会冲突 数字分析法 抽取关键字的一部分作为hash值 例如手机号,一般可以取后4位或者后4位的变形作为hash值,(公司内部场景) 平方取中法 折

js数据结构与算法——字典与散列表

<script> //创建字典 function Dictionary(){ var items = {}; this.set = function(key,value){ //向字典添加一个新的项 items[key] = value; } this.remove = function(key){ //从字典移除一个值 if(this.has(key)){ delete items[key]; return true; } return false; } this.has = functio

回顾散列表的7点

1.散列表(hash table)的实现成为散列(hashing),是一种以常数平均时间执行输入.删除和查找的技术.但是那些需要元素间任何排序信息的数操作将不会得到有效的支持. 2.散列函数示例 int hash(const string & key, int tableSize) { int hashVal=0; for(int i=0;i<key.length();i++) hashVal=37*hashVal+key[i]; hashVal %= tableSize; if(hashV

解决hash冲突之分离链接法

解决hash冲突之分离链接法 分离链接法:其做法就是将散列到同一个值的所有元素保存到一个表中. 这样讲可能比较抽象,下面看一个图就会很清楚,图如下 相应的实现可以用分离链接散列表来实现(其实就是一个linkedList数组) 至于基本的增加.删除和查询的思路都是先根据散列函数来确定遍历哪个链表.然后再到被确定的链表中执行一次查找,然后再进行相应的操作. 接下来就讲几个注意点吧 (一)什么时候需要rehash来扩大散列表的大小 讲这个的时候,先介绍一下什么是装填因子. 装填因子 = 关键字个数 /

习题5.11 分离链接法的删除操作函数 (20分)

试实现分离链接法的删除操作函数. 函数接口定义: bool Delete( HashTable H, ElementType Key ); 其中HashTable是分离链接散列表,定义如下: typedef struct LNode *PtrToLNode; struct LNode { ElementType Data; PtrToLNode Next; }; typedef PtrToLNode Position; typedef PtrToLNode List; typedef struc

Python数据结构——散列表

散列表的实现常常叫做散列(hashing).散列仅支持INSERT,SEARCH和DELETE操作,都是在常数平均时间执行的.需要元素间任何排序信息的操作将不会得到有效的支持. 散列表是普通数组概念的推广.如果空间允许,可以提供一个数组,为每个可能的关键字保留一个位置,就可以运用直接寻址技术. 当实际存储的关键字比可能的关键字总数较小时,采用散列表就比较直接寻址更为有效.在散列表中,不是直接把关键字用作数组下标,而是根据关键字计算出下标,这种 关键字与下标之间的映射就叫做散列函数. 1.散列函数