链式哈希表的接口定义

关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html

链式哈希表的操作与属性有:初始化、销毁、插入元素、删除元素、查找元素、获取哈希表中无数的个数。

chtbl_init


int cltbl_init(CHTbl *htbl, int buckts, int (*h)(const void *key), int (*match)(const void *key1,const void *key2), void (*destroy)(void *data));

返回值如果哈希表初始化成功,返回0,否则返回-1。

描述:  初始化htbl指定的链式哈希表。

在对链式哈希表执行其他操作之前,必须要先初始化。哈希表中所分配的“桶”的个数将由buckets指定。函数指针h指向一个用户定义的哈希函数,此函数会将键进行散列。函数指针match指向一个用户定义的函数,此函数用于判断两个键是否匹配。如果key1等于key2,返回1;否则返回其他值。参数destroy是一个函数指针,通过调用chtbl_destroy来释放动态分配的内存空间。如果哈希表中的数据不需要释放,那么destroy应该指向NULL。

复杂度: O(m),m是哈希表中“桶”的个数。

chtbl_destroy


 void cltbl_destroy(CHTbl *htbl);

返回值:无

描述:   销毁htbl指定的链式哈希表。

在调用chtbl_destroy之后不再允许进行其他操作,除非再次调用chtbl_init。chtbl_destroy会删除哈希表中的所有元素,并同时释放chtbl_init中参数destroy不为NULL的成员所占用的内存空间。

复杂度: O(m),m是哈希表中“桶”的个数。

chtbl_insert


int cltbl_insert(CHTbl *htbl,const void *data);

返回值如果插入元素成功则返回0;如果哈希表中已经包含此元素,返回1;否则返回-1。

描述:   向htbl指定的链式哈希表中插入一个元素。

新元素包含一个指向data的指针,只要元素仍然存在于哈希表中,此指针就一直有效。与data相关的内存空间将由函数的调用者来管理。

复杂度: O(m),m是哈希表中“桶”的个数。

chtbl_remove


int cltbl_remove(CHTbl *htbl,const void **data);

返回值如果删除元素成功则返回0;否则返回-1。

描述:   从htbl指定的链式哈希表中删除与data匹配的元素。

返回时data指向已经删除元素中存储的数据。与data相关的内存空间将由函数的调用者来管理。

复杂度: O(1)

chtbl_lookup


int cltbl_lookup(const CHTbl *htbl,const void **data);

返回值如果在哈希表中找到元素则返回0;否则返回-1。

描述:   查找htbl指定的链式哈希表中与data相匹配的元素。

如果找到,在函数返回时,data将指向哈希表中相匹配元素中的数据。

复杂度: O(1)

chtbl_size


int cltbl_size(CHTbl *htbl);

返回值哈希表中的元素个数。

描述:   获取htbl指定的链式哈希表的元素个数的宏。

复杂度: O(1)

链式哈希表的实现与分析

示例:链式哈希表抽象数据类型的头文件

#ifndef CHTBL_H
#define CHTBL_H #include <stdlib.h> #include "list.h" /*为哈希表定义一个数据结构*/
typedef struct CHTbl_
{
int buckets; /*1、表中分配的“桶”的个数*/ int (*h)(const void *key); /*2、指向哈希函数*/
int (*match)(const void *key1, const void *key2); /*3、指向match函数*/
int (*destroy)(void *data); /*4、指向销毁函数*/ int size; /*5、表中元素的数量*/
List *table; /*6、存储“桶”的数组*/
}CHTbl; /*公用接口*/
int chtbl_init(CHTbl *htbl, int buckets, int(*h)(void *key), int (*match)(const void *key1, const void *key2),
void(*destroy)(void *data)); int chtbl_destroy(CHTbl *htbl); int chtbl_insert(CHTbl *htbl, const void *data); int chtbl_remove(CHTbl *htbl,void **data); int chtbl_lookup(const CHTbl *htbl,void **data); #define chtbl_size(htbl)((htbl)->size) #endif // CHTBL_H

示例:链式哈希表的实现

#include <stdlib.h>
#include <string.h> #include "list.h"
#include "chtbl.h" /*chtbl_init 初始化链式哈希表*/
int chtbl_init(CHTbl *htbl, int buckets, int (*h)(const void *key),
int (*match)(const void *key1,const void *key2),void (*destroy)(void *data))
{
int i; /*首先,为“桶”分配空间*/
if((htbl->table = (List *)malloc(buckets*sizeof(List)))==NULL)
return -; /*然后,调用list_init初始化这些桶*/
htbl->buckets = buckets;
for(i=;i<htbl->buckets;i++)
list_init(&htbl->table[i],destroy); /*接着,封装h,match,destroy函数*/
htbl->h = h;
htbl->match = match;
htbl->destroy = destroy; /*最后,将size值设置为0*/
htbl->size = ; return ;
} /*chtbl_destroy 销毁链式哈希表*/
void chtbl_destroy(CHTbl *htbl)
{
int i; /*首先,删除每个“桶”中的元素*/
for(i=;i<htbl->buckets;i++)
{
list_destroy(&htbl->table[i]);
} /*然后,释放由chtbl_init分配的内存空间*/
free(htbl->table); /*最后,哈希表不再允许任何操作,清除这一结构作为错误预防*/
memset(htbl,,sizeof(CHTbl)); return ;
} /*chtbl_insert 向链式哈希表中插入元素*/
int chtbl_insert(CHTbl *htbl,const void *data)
{
void *temp;
int bucket,retval; /*首先,调用chtbl_lookup检查哈希表中是否已经存有该元素*/
temp = (void *)data;
if(chtbl->lookup(htbl,&temp)==)
return ; /*如果未存有该元素,接着将新元素的键散列*/
bucket = htbl->h(data) % htbl->buckets; /*然后,根据哈希编码将新元素插入哈希表中相应位置的“桶”中*/
if((retval = list_ins_next(&htbl->table[bucket],NULL,data))==)
htbl->size++;
return retval;
} /*chtbl_remove 删除表中的元素*/
int chtbl_remove(CHTbl *htbl,void **data)
{
ListElmt *element,*prev;
int bucket; /*首先,哈希(散列)元素的键*/
bucket = htbl->h(*data)%htbl->buckets; /*接着,查找与元素的键相匹配的桶*/
prev = NULL;
for(element = list_head(&htbl->table[bucket]);element != NULL; element = list_next(element))
{
if(htbl->match(*data,list_data(element)))
{
/*然后,调用list_rem_next删除元素*/
if(list_rem_next(&htbl->table[bucket],prev,data) == 0)
{
htbl->size--;
return 0;
}
else
{
return -1;
}
}
prev = element;
}
/*遍历结束后,没有找到元素,返回-1*/
retrun -1;
} /*chtbl_lookup 查找元素*/
int chtbl_lookup(const CHTbl *htbl,void **data)
{
ListElmt *element;
int bucket; /*首先,散列要查找元素的键*/
bucket = htbl->h(*data) % htbl->buckets; /*接着,查找与元素相匹配的桶*/
for(element = list_head(&htbl->table[bucket]; element != NULL; list_next(element))
{
if(htbl->match(*data,list_data(element))
/*从表中返回该元素*/
*data = list_data(element);
return 0;
}
/*遍历结束后,没有找到元素,则返回-1*/
return -1;
}

数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)的更多相关文章

  1. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  2. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  3. java哈希表(线性探测哈希表。链式哈希表)

    哈希表(散列表) 通过哈希函数使元素的存储位置与它 的关键码之间能够建立一一映射的关系,在查找时可以很快找到该元素. 哈希表hash table(key,value) 的做法其实很简单,就是把Key通 ...

  4. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  5. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  6. 什么叫哈希表(Hash Table)

    散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...

  7. golang数据结构之散哈希表(Hash)

    hash.go package hash import ( "fmt" ) type Emp struct { ID int Name string Next *Emp } //第 ...

  8. 哈希表(Hash table)

  9. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

随机推荐

  1. [Python学习] Django 权限控制

    本文为大家讲解 Django 框架里自带的权限模型,从理论到实战演练,带领大家了解 Django 里权限是怎么一回事. 一.主要内容 1.什么是权限管理? 2.Web 权限 3.Django 权限机制 ...

  2. Class StatusesTableSeeder does not exist 如何解决

    Class StatusesTableSeeder does not exist错误如何解决 Laravel 5.* 执行seeder命令出现错误的解决方法     最近在使用Laravel开发一个项 ...

  3. iOS微信运动 刷分

    修改 iOS微信运动的数据  很简单,这里记录下实现步骤. 首先要安装Theos,具体安装步骤就不说了.网上很多. 大体安装步骤: sudo brew install dpkg sudo brew i ...

  4. ORM框架 EF - code first 的封装 优化一

    上一节我们讲到对EF(EntityFramework)的初步封装,任何事情都不可能一蹴而就,通过大量的实际项目的实战,也发现了其中的各种问题.在这一章中,我们对上一章的EF_Helper_DG进行优化 ...

  5. Sql Server Configuration Manager 网络配置为空,没有实例

    新用户一天内不准提问...Sql Server Configuration Manager 网络配置为空,没有实例无法设置ip和端口进行连接..

  6. DeepLearning.ai学习笔记(四)卷积神经网络 -- week2深度卷积神经网络 实例探究

    一.为什么要进行实例探究? 通过他人的实例可以更好的理解如何构建卷积神经网络,本周课程主要会介绍如下网络 LeNet-5 AlexNet VGG ResNet (有152层) Inception 二. ...

  7. 大白话说Java泛型(一):入门、原理、使用

    文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java泛型(一):入门.原理.使用> 远在 JDK 1.4 版本的时候,那时候是没有泛型的概念的.当时 Java 程序员们写集合类的 ...

  8. sprintf的用法

    正文:printf 可能是许多程序员在开始学习C 语言时接触到的第二个函数(我猜第一个是main),说起来,自然是老朋友了,可是,你对这个老朋友了解多吗?你对它的那个孪生兄弟sprintf 了解多吗? ...

  9. nginx的配置

    1. brew install nginx 2.brew services list 3.brew services start nginx 4.brew servicies stop nginx 5 ...

  10. 如何实现VM框架中的数据绑定

    作者:佳杰 本文原创,转载请注明作者及出处 如何实现VM框架中的数据绑定 一:数据绑定概述 视图(view)和数据(model)之间的绑定 二:数据绑定目的 不用手动调用方法渲染视图,提高开发效率:统 ...