算法:分离链表法散列表

hash.h

#ifndef _HASHTABLE_H
#define _HASHTABLE_H

#define MinSize 10

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

HashTable InitializeHashTable(int TableSize);
Position Find(ElementType key,HashTable H);
void Insert(ElementType key,HashTable H);
void Delete(ElementType key,HashTable H);

#endif

struct ListNode
{
    ElementType key;
    Position next;
};
typedef Position List;

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

Hash.c

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

//获取下一个素数
static int NextPrime(int N)
{
    int i;
    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:;
    }
    return N;
}
//Hash函数
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;
    int i;
    H=(HashTable)malloc(sizeof(struct HashNode));
    if(H==NULL){
        printf("out 0f space");
        return NULL;
    }
    H->TableSize=NextPrime(TableSize);
    //分配链表数组空间
    H->TheLists=malloc(sizeof(struct List))*H->TableSize
    if(H->TheLists==NULL){
        printf("out of space");
        return NULL;
    }
    //分配链表表头空间
    for(i=0;i<H->TableSize;++i){
        H->TheLists[i]=malloc(sizeof(struct ListNode));
        if(H->TheLists[i]==NULL){
            printf("out of space");
            return NULL;
        }
        H->TheLists[i]->next=NULL;
    }
    return H;
}
Position Find(ElementType key,HashTable H)
{
    Position P;
    List L;
    L=H->TheLists[Hash(key,H->TableSize)];
    P=L->next;
    while(P!=NULL&&strcmp(P->key,key)!=0){
        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){
            printf("out of space");
            return NULL;
        }
        L=H->TheLists[Hash(key,H->TableSize)];
        NewCell->next=L->next;
        NewCell->key=malloc(strlen(key))+1;
        strcpy(NewCell->key,key);
        NewCell->key[strlen(key)]=‘\0‘;
        L->next=NewCell;
    }
}
void Delete(EelmentType key,HashTable H)
{
    Position Pos,Pre;
    List L;
    Pos=Find(key,H);
    L=H->TheLists[Hash(key,H->TableSize)];
    for(Pre=L;Pre!=NULL;Pre=Pre->next){
        if(Pre->next==Pos){
            Pre->next=Pos->next;
            free(Pos->key);
            free(Pos);
            break;
        }
    }
}
void DestoryTable(HashTable H)
{
    Position P,Tmp;
    int i;
    for(i=0;i<H->TableSize;++i){
        P=H->TheLists[i];
        while(P!=NULL){
            Tmp=P->next;
            free(P->key);
            free(P);
            P=Tmp;
        }
    }
    free(H);
}
时间: 2024-10-19 12:46:19

算法:分离链表法散列表的相关文章

--算法分析与设计--课程作业--【顺序统计】--【采用链表法散列表】--【开放地址法(双重散列)】

本次作业大力感谢以下量 参考信息 经典算法总结之线性时间做选择 http://www.cnblogs.com/javaspring/archive/2012/08/17/2656208.html 11.4 双重散列法 : http://blog.csdn.net/zixiawzm/article/details/6746946 [未完待续]

算法:开放定址法散列表

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 *Cel

《算法图解》chap5 散列表

线索Cues 笔记Notes 散列表的内部机制(实现,冲突,散列函数) 应用案例 一.散列表=散列函数+数组 散列函数特点: 将相同的输入映射到相同的数字 将不同的输入映射到不同的数字,但其实这样的函数几乎不会存在.所以会有冲突的存在:两个键分配的位置相同. 知道数组有多大,只返回有效的索引 散列表是由键和值组成的. 冲突的处理方式,当两个键映射到同一个位置,就在这个位置存储一个链表. 二. 查找某人的电话号码 投票,一人只能投一次.如果没有投过票就投票成功并且保存.投过就不让投 缓存:网站将数

算法导论11.2散列表Hash tables链式法解决碰撞

/* * IA_11.2ChainedHash.cpp * * Created on: Feb 12, 2015 * Author: sunyj */ #include <stdint.h> #include <iostream> #include <string.h> // CHAINED-HASH-INSERT(T, x) // insert x at the head of list T[h(x.key)] // CHAINED-HASH-SEARCH(T, k)

散列表的开放寻址法

开放寻址法(open addressing)中,所有元素都存放在槽中,在链表法散列表中,每个槽中保存的是相应链表的指针,为了维护一个链表,链表的每个结点必须有一个额外的域来保存它的前戏和后继结点.开放寻址法不在槽外保存元素,不使用指针,也不必须为了维护一个数据结构使用额外的域,所有可以不用存储指针而节省的空间,使得可以用同样的空间来提供更多的槽,也潜在地减少了冲突,提高了检索速度. 为了使用开放寻址法插入一个元素,需要连续地检查散列表,或称为探查(probe),直到找到一个空槽来放置待插入的关键

Python数据结构——散列表

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

散列表的C语言实现-分离链接法

一:散列表的定义: 散列表的实现常常叫做散列,散列是一种用于以常数平均时间执行插入,查找,删除的技术,但是,那些需要元素间任何排序信息的操作将不会得到支持,如findmin,findmax等等.散列表的优点很明显,它的查询时间为常数,速度非常快,缺点就是元素间没有排序,对于一些需要排序的场合不适用.理想的散列表数据结构就是一个包含有关键字的具有固定大小的数组,用一个散列函数来跟据关键字的值来将关键字插入到表中.这是散列的基本想法,剩下的问题是要选择一个好的散列函数,当俩个关键字散列到同一个值得时

散列表之链接法

散列表之链接法 散列表的定义 散列表的基本操作 散列表的编码实现 散列表的设计 主测试文件 编译运行 结论 注意: 本文中的所有代码你可以在这里 https://github.com/qeesung/algorithm/tree/master/chapter11/11-2/hashTable(这里会及时更新) 或者这里 http://download.csdn.net/detail/ii1245712564/8804203 找到 散列表之链接法 在之前的文章<散列表之直接寻址表>中介绍了散列表

深入浅出数据结构C语言版(14)——散列表

我们知道,由于二叉树的特性(完美情况下每次比较可以排除一半数据),对其进行查找算是比较快的了,时间复杂度为O(logN).但是,是否存在支持时间复杂度为常数级别的查找的数据结构呢?答案是存在,那就是散列表(hash table,又叫哈希表).散列表可以支持O(1)的插入,理想情况下可以支持O(1)的查找与删除. 散列表的基本思想很简单: 1.设计一个散列函数,其输入为数据的关键字,输出为散列值n(正整数),不同数据关键字必得出不同散列值n(即要求散列函数符合单射条件) 2.创建一个数组HashT