精华内容
下载资源
问答
  • c语言实现哈希表查找
    万次阅读 多人点赞
    2017-08-18 15:39:34

    哈希表(散列表)是直接通过关键字key得到要查找的记录的内存存储位置。

    散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。

    采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表或者哈希表。

    整个散列过程分为两步:

    1.在存储时,通过散列函数计算记录的散列地址,并按此地址存储该记录。

    2.当查找记录时,通过同样的散列函数计算记录的散列地址,按此地址方位记录。

    因此散列技术既是一种存储方法也是一种查找方法,数据元素之间不存在逻辑关系。

    散列技术最合适的问题是查找与给定值相等的记录。

    散列函数设计的两个原则是计算简单、散列地址分布均匀。

    最长用的方法是除留余数法,f(key)=key mod p(p小于等于散列表的长度m)。

    但散列函数可能会造成冲突,即两个不同的记录求得的散列地址一样,解决散列冲突最常用的方法为开放定址法。一旦发生冲突,就去寻找下一个散列地址,只要散列表足够大,空的散列地址总能找到。

    以下程序在DEV C++中调试运行通过。

    #include<stdio.h>
    #include<stdlib.h>
    
    #define HASHSIZE 12
    #define NULLKEY -32768
    typedef struct
    {
    	int *elem;
    	int count;
    }HashTable;
    int m=0;
    
    //初始化散列表
    int InitHashTable(HashTable *H)
    {
    	int i;
    	m=HASHSIZE;
    	H->count=m;
    	H->elem=(int*)malloc(m*sizeof(int));
    	for(i=0;i<m;i++)
    		H->elem[i]=NULLKEY;
    	return 1;
     }
     //散列函数
     int Hash(int key)
     {
     	return key%m;
      } 
      //插入关键字进入散列表
      void InsertHash(HashTable *H,int key)
      {
      	int addr=Hash(key);
      	while(H->elem[addr]!=NULLKEY)
      		addr=(addr+1)%m;
      	H->elem[addr]=key;
       } 
       
    //散列表查找关键字
    int SearchHash(HashTable H,int key,int *addr)
    {
    	*addr=Hash(key);
    	while(H.elem[*addr]!=key)
    	{
    		*addr=(*addr+1)%m;
    		if(H.elem[*addr]==NULLKEY||*addr==Hash(key))
    		{
    			return -1;
    		}
    	}
    	return *addr;
     } 
      
    int main()
    {
    	int a[12]={12,67,56,16,25,37,22,29,15,47,48,34};
    	HashTable H;
    	int i;
    	InitHashTable(&H);
    	for(i=0;i<m;i++)
    		InsertHash(&H,a[i]);
    	printf("插入之后的哈希表为:");
    	for(i=0;i<m;i++)
    		printf("%d,",H.elem[i]);
    	int addr,j;
    	j=SearchHash(H,a[5],&addr);
    	printf("搜索到a[5]的地址是:%d",j);
    }

    运行结果如图所示。


    如果没有冲突,哈希表查找算法的时间复杂度为O(1)。

    更多相关内容
  • 本文为大家分享了C语言基于哈希表实现通讯录的具体代码,供大家参考,具体内容如下 1.需求分析 本演示程序用C语言编写,完成哈希表的生成,电话号码的插入、以及查找等功能。  (1)按提示输入相应的联系人的相关...
  • C语言设计哈希表实现图书查找系统,完成相应的建表和查表程序。从键盘输入各图书相关信息,分别以图书编号为关键字建立散列表。待填入哈希表的书号至少30个;构造合适的哈希函数。 1) 记录由外部输入。 2) 将生成...
  • c语言实现哈希表

    千次阅读 2022-03-23 21:00:27
    哈希表

    最近在做FTP服务器项目的时候,需要统计服务器的最大连接数和每IP连接数。
    每IP连接数:指的是服务器连接同一个IP地址的次数
    最大连接数:服务器最多可以连接客户端的个数
    其中前者需要用到哈希表。
    c++中,我们可以直接使用map或者unordered_map来产生pair键值对,c语言中没有对应的库,所以需要自己实现一下hash表的结构。
    如下图所示:

    1. hash表中保存的是哈希函数,桶结点的个数,以及二级指针:存储的是桶结点的地址。
    2. 每一个桶结点中存放的是哈希结点的地址,是一个一级指针,桶结点的个数为4个。
    3. 每一个hash结点是由key指针,value指针,结点的前驱指针,后继指针构成的。这里之所以存放的是指针,是因为它可以接收任意类型的数据。

    一般哈希函数选择的是除留余数法
    hash(key)=key%p,其中p≤buckets,取最接近于buckets的质数即可。
    需要注意的是,由于经过哈希函数映射之后,关键码对应的位置对应滴位置可能是相同的,因此采用开散列的方法,使用链表的结构将所有相同位置的关键码串联起来。
    如下图所示:为了方便起见,11,22,33处对应的是哈希结点的地址而不是key值。链表的插入采用的是头插,提升效率。
    例如key=0,11,22,33对应的地址都是相同的,可以采用链表的方式将其连接。
    在这里插入图片描述
    1.hash_node的结构:

    typedef struct hash_node
    {
    	void *key;
    	void *node;
    	struct hash_node* prev;
    	struct hash_node* next;
    }hash_node_t;
    

    2.hash表的结构
    //函数指针 对应的函数名是hashfunc_t:参数一个为int,一个为void。经过typedef之后,可以通过hashfunc_t来代表函数指针。

    typedef unsigned int (*hashfunc_t)(unsigned int, void*);
    
    
    struct hash
    {
    	unsigned int buckets; //对应的桶的大小
    	hashfunc_t hash_func; //保存的hash函数的地址
    	hash_node_t **nodes; //二级指针,存放桶结点的首地址
    };
    

    3.hash表的生成
    类型的重定义

    typedef struct hash hash_t; 将hash表重定义为hash_t
    

    哈希表的初始化

    hash_func是自己定义的,这里存放的是函数地址。定义的hash_func如下所示:

    unsigned int hash_func(unsigned int bucket_size, void* key)
    {
    	return (*(unsigned int*)key) % bucket_size;
    }
    

    注意,这里结点的大小是桶结点的个数乘以每一个指针的内存大小,对hash_nodes所指的内存空间进行内存的初始化,指针置为NULL。

    hash_t *hash_alloc(unsigned int buckets, hashfunc_t hash_func)
    {
    	hash_t *hash = (hash_t *)malloc(sizeof(hash_t));
    	assert(hash != NULL);
    	hash->buckets = buckets;
    	hash->hash_func = hash_func;
    	int size = buckets * sizeof(hash_node_t *);
    	hash->nodes = (hash_node_t **)malloc(size);
    	memset(hash->nodes, 0, size);
    	return hash;
    }
    

    下面部分是获取关键码对应的桶结点的位置,通过hash函数映射之后计算出对应的bucket,将对应结点的地址返回。

    hash_node_t** hash_get_bucket(hash_t* hash, void* key)
    {
    	unsigned int bucket = hash->hash_func(hash->buckets, key);
    	if (bucket >= hash->buckets)
    	{
    		fprintf(stderr, "bad bucket lookup\n");
    		exit(1);
    	}
    	return &(hash->nodes[bucket]);
    }
    

    下面部分是通过关键值key来查询对应的结点,例如我们需要查找key=22的结点,找到buckets的位置之后,链表向后遍历即可。
    之前自己理解的时侯,总觉得桶结点已经找到了,为什么还需要向后遍历呢,其实是需要的,因为当前桶的头结点存储的key值可能不是我们需要找的,比如上面的例子中,buckets[0]存储的是key=0的元素的地址。

    1. 获取当前key值对应的桶结点的地址。
    2. node指向当前的桶结点的头部,依次向后寻找,直到node指向的key值和要寻找的key值相等时,代表找到了对应的结点,因此返回该结点即可。
    3. memcmp(void * str1,void * str2,size_t n)用来对比str1和str2前n个字节大小是否相等。
    hash_node_t* hash_get_node_by_key(hash_t* hash, void* key, unsigned int key_size)
    {
    	hash_node_t** bucket = hash_get_bucket(hash, key);
    	hash_node_t* node = *bucket;
    	if (node == NULL)
    	{
    		return NULL;
    	}
    	while (node != NULL && memcmp(node->key, key, key_size) != 0)
    	{
    		node = node->next;
    	}
    	return node;
    }
    

    查询key值对应的value值

    代码如下所示:如果找到key值,就返回当前key值对应的value值。否则返回NULL

    void* hash_lookup_entry(hash_t* hash, void* key, unsigned int key_size)
    {
    	hash_node_t* node = hash_get_node_by_key(hash, key, key_size);
    	if (node == NULL)
    	{
    		return NULL;
    	}
    	return node->value;
    }
    

    向哈希表中添加结点

    需要给定key值的地址,对应的大小,value值的地址,对应的大小。

    1. 首先查找,如果已经存在相同的key值,那么程序就会报错。
    2. 其次申请新的hash结点,对前驱和后继赋空。将key和value的值拷贝到node->key和node->value中。
    3. 获取当前key值对应的bucket的地址。
    4. 如果为空,代表不存在,直接将结点插入,如果不为空,代表地址发生了冲突,因此需要将新的结点插入到头部。
      在这里插入图片描述
    void hash_add_entry(hash_t* hash, void* key, unsigned int key_size, void* value, unsigned int value_size)
    {
    	if (hash_lookup_entry(hash, key, key_size))
    	{
    		fprintf(stderr, "duplicate hash key\n");
    		return;
    	}
    	hash_node_t* node = malloc(sizeof(hash_node_t));
    	node->prev = NULL;
    	node->next = NULL;
    	node->key = malloc(key_size);
    	memcpy(node->key, key, key_size);
    	node->value = malloc(value_size);
    	memcpy(node->value, value, value_size);
    	hash_node_t** bucket = hash_get_bucket(hash, key);
    	if (*bucket == NULL)
    	{
    		*bucket = node;
    	}
    	else
    	{
    		// 将新结点插入到链表头部
    		// 当前结点的后继指向下一个结点。
    		node->next = *bucket;
    		// 
    		(*bucket)->prev = node;
    		*bucket = node;
    	}
    }
    

    释放hash表中的结点

    1. 检查key值是否存在,存在的话,释放对应的key和value。
    2. 如果被释放的结点存在前驱指针,那么前驱指针的下一个指针指向当前被释放结点的下一个结点。如果不存在前驱指针,那么说明当前指针是头结点,故找到对应的桶结点的位置,将桶结点指向当前结点的下一个结点。
    3. 当前结点下一个结点不为空,下一个结点的前驱结点指向当前结点的前驱结点。
      在这里插入图片描述
    void hash_free_entry(hash_t* hash, void* key, unsigned int key_size)
    {
    	hash_node_t* node = hash_get_node_by_key(hash, key, key_size);
    	if (node == NULL)
    	{
    		return;
    	}
    	free(node->key);
    	free(node->value);
    	if (node->prev)
    	{
    	  // 第一步
    		node->prev->next = node->next;
    	}
    	else
    	{
    		hash_node_t** bucket = hash_get_bucket(hash, key);
    		*bucket = node->next;
    	}
    	// 后继结点的前驱连接被删除结点的前驱(第二步)
    	if (node->next)
    		node->next->prev = node->prev;
    	// 释放结点
    	free(node);
    }
    

    附录:假设给定的key值不是int值,要怎么处理呢?参考了一下别人的代码:将对应的字符串转为相对应的ASII值,再进行计算即可。

    unsigned int hash_func_str(unsigned int bucket_size, char* key)
    {
    	int sum = 0;
    	char* tmp = key;
    	while (*tmp != '\0')
    	{
    		sum += *tmp;
    		tmp++;
    	}
    	return sum % bucket_size;
    }
    

    打印hash表

    1.key值为数字的时候

    void printhash(hash_t* hash1)
    {
    	hash_node_t** z = hash1->nodes;
    	int i = 0;
    	for (i = 0; i < hash1->buckets; ++i)
    	{
    		if (z[i] == NULL)
    			continue;
    		while (z[i]!= NULL)
    		{
    			printf("key:%d,value:%d\n", *(int*)(z[i]->key), *(int*)(z[i]->value));
    			z[i] = z[i]->next;
    		}
    	}
    }
    

    2.key值为字符串的时候

    void printhash(hash_t* hash1)
    {
    	hash_node_t** z = hash1->nodes;
    	int i = 0;
    	for (i = 0; i < hash1->buckets; ++i)
    	{
    		if (z[i] == NULL)
    			continue;
    		while (z[i]!= NULL)
    		{
    			printf("key:%s,value:%d\n", (char*)z[i]->key, *(int*)(z[i]->value));
    			z[i] = z[i]->next;
    		}
    	}
    }
    

    测试函数如下所示:

    static struct hash* ip_count_hash;
    int main()
    {
    	ip_count_hash = hash_alloc(17, hash_func_str);
    	char key1[] = "ab";
    	//printf("%d\n", sizeof(key1));
    	int value1 = 100;
    	char key2[] = "bc";
    	int value2 = 20;
    	char key3[] = "cde";
    	int value3 = 30;
    	hash_add_entry(ip_count_hash, &key1, sizeof(key1), &value1,sizeof(int));
    	hash_add_entry(ip_count_hash, &key2, sizeof(key2), &value2, sizeof(int));
    	hash_add_entry(ip_count_hash, &key3, sizeof(key3), &value3, sizeof(int));
    	printhash(ip_count_hash);
    	return 0;
    }
    

    后续再研究闭散列吧,c语言和c++的实现差距还是挺大的,本篇主要是为了FTP服务器的IP数目限制所写的,比较简单一点,有兴趣的同学可以参考一下这篇博客哦
    FTP项目第三部分
    在这里插入图片描述

    展开全文
  • C语言基于哈希表的电话簿
  • 在windows环境下,使用codeblocks进行哈希表的创建、增添、删除、寻找、打印
  • C语言实现哈希表

    千次阅读 2021-05-17 11:06:30
    C语言实现哈希表 简介:遇到散列表冲突时,采用链表分离的方式 哈希表在根据内容查找时,它的时间复杂度相对于要逐一遍历的数组或者链表要小。 散列算法:主要由md5(消息摘要算法),sha1(安全散列) ,这两者不可靠。...

    C语言实现哈希表

    简介:
    哈希表在根据内容查找时,它的时间复杂度相对于要逐一遍历的数组或者链表要小。

    散列算法:主要由md5(消息摘要算法),sha1(安全散列) ,这两者不可靠。sha2(安全散列2 sha256/512)目前还没冲突,较为可靠。

    散列冲突:多个数据,进行散列之后的散列值相同,此时会存在散列冲突。
    常见的解决方法:有线性探测、平方探测、二次散列、链表分离、链表分离改良实现(链表+红黑树)。

    该程序:采用链表分离的方法解决散列冲突。适合初学者学习。
    哈希表
    该图为本程序的图解,结合此图看程序时有对哈希表有较好的理解。

    //sanlie.c 哈希表的实现
    //采用链表的方式
    //遇到散列冲突时,采用链表分离的方式
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //哈希表中数据元素的结构体
    typedef struct
    {
        char *key; //关键字
        char *value;
    } Element;
    
    //数据元素单链表
    typedef struct Node
    {
        Element student;   //数据元素
        struct Node *next; //next指针
    } Node;
    
    //哈希表
    typedef struct
    {
        Node *head; //数据元素存储
        int size;   //当前表中的大小,表长
        int count;  //哈希表中的数据元素的个数
    } HashTable;
    
    //初始化哈希表
    HashTable *inittable(int tablesize)
    {
        HashTable *table = (HashTable *)malloc(sizeof(HashTable));
        table->size = tablesize;
        //分配和初始化单链表数据元素的头结点
        table->head = (Node *)malloc((table->size) * sizeof(Node));
        memset(table->head, 0, sizeof(Node) * (table->size));
        table->count = 0; //现有的元素的个数
    
        return table;
    }
    
    //哈希函数
    int hash(HashTable *table, char *key)
    {
        int sum = 0; //字符串的ASNI之和
        for (int i = 0; i < strlen(key); i++)
        {
            sum += key[i];
        }
    
        return sum % table->size;
    }
    
    //在哈希表中查找关键字
    Node *find(HashTable *table, char *key)
    {
        int ii = hash(table, key);
    
        Node *node = table->head[ii].next;
    
        //遍历单链表
        while ((node != NULL) && (node->student.key != key))
        {
            node = node->next;
        }
    
        return node;
    }
    
    //往哈希表中插入元素
    int put(HashTable *table, char *key, char *value)
    {
        //从哈希表中查找元素
        Node *ee = find(table, key);
    
        if (ee != NULL)
        {
            printf("元素已经存在。\n");
            return 0;
        }
    
        int ii = hash(table, key);
    
        Node *node = (Node *)malloc(sizeof(Node));
        node->student.key = key;
        node->student.value = value;
    
        //追加在对应位置的头结点后面
        node->next = table->head[ii].next;
        table->head[ii].next = node;
    
        table->count++;
        return 1;
    }
    
    //遍历哈希表
    void Print(HashTable *table)
    {
        for (int i = 0; i < table->size; i++)
        {
            Node *node = table->head[i].next;
    
            while (node)
            {
                printf("%s-%s  ", node->student.key, node->student.value);
                node = node->next;
            }
            printf("\n");
        }
    
        printf("\n");
    }
    
    //从哈希表中删除元素
    int get(HashTable *table, char *key)
    {
        int ii = hash(table, key);
    
        Node *node = &table->head[ii];
    
        //遍历单链表,node停留在待删除关键结点key的前一结点
        while ((node != NULL) && (node->next->student.key != key))
        {
            node = node->next;
        }
    
        if (node->next == NULL)
            return 0; //查找失败
    
        Node *tmp = node->next; //tmp为将要删除的结点
    
        node->next = tmp->next;
    
        free(tmp); //释放结点
    
        table->count--;
    
        return 1;
    }
    
    int main(int argc, char const *argv[])
    {
        HashTable *table = inittable(5);
    
        put(table, "alice", "alice info");
        put(table, "bob", "bob info");
        put(table, "hack", "hack info");
    
        Print(table);
    
        get(table, "bob");
        Print(table);
    
        Node *node = find(table, "hack");
        if (node != NULL)
            printf("找到%s-%s\n", node->student.key, node->student.value);
    
        Node *node1 = find(table, "bob");
        if (node1 != NULL)
            printf("找到%s-%s\n", node1->student.key, node1->student.value);
    
        return 0;
    }
    
    展开全文
  • C语言实现简单哈希表

    千次阅读 2022-01-06 20:17:59
    什么是哈希表 哈希表,也叫散列表,是根据关键码值而直接进行访问的数据结构。通俗点说,就是通过关键值(key)映射到表中的某个位置,以便可以直接访问该节点,以提高查找速度。这个映射函数就是散列函数。 举个例子...

    什么是哈希表

    哈希表,也叫散列表,是根据关键码值而直接进行访问的数据结构。通俗点说,就是通过关键值(key)映射到表中的某个位置,以便可以直接访问该节点,以提高查找速度。这个映射函数就是散列函数。
    举个例子,我们有很多员工的信息需要存储,比如张三,李四,王五;一般来说我们可以用链表将他们的信息存储起来,当我们需要某个员工的信息时,遍历链表查找出其信息即可。这样的弊端可想而知:查找效率太低。而如果我们有个函数f(x),能将张三,李四,王五分别映射成1,2,3。那我们可以直接将张三,李四,王五的信息分别存储在链表的1,2,3个节点。需要查找某个员工信息时,根据其映射值,直接查找链表对应位置即可,这样便大大提高了查找效率。事实上,我们将f(x)成为散列函数,存放映射记录的结构,就叫散列表(哈希表)。

    哈希表的性能

    由于哈希表高效的特性,查找或者插入的情况在大多数情况下可以达到O(1),时间主要花在计算hash值上。最糟糕的情况是所有的key都被映射为同一个地址,此时哈希表退化成链表,时间复杂度变为O(n)。但这种情况几乎不会发生。实际上,哈希表是以空间换时间。哈希表会消耗更多的内存,以换取更快的查找效率。

    哈希表实现

    第一步,构造哈希表。链表结点至少需要三个成员,关键值key,指向key对应数据的结构指针value(最简单就是char *,也可以是结构体指针),链表结点指针next。我会习惯多加一个free_value,它是一个函数指针,作用是free掉value指针指向的内存。如下:

    struct kv
    {
        char *key;
        void *value;
        void (*free_value)(void *);
        struct kv *next;
    };
    

    哈希表创建函数如下(hashTable *就是哈希表指针,下同):

    hashTable *hash_table_create()
    {
        hashTable *p = (hashTable *)malloc(sizeof(hashTable));
        if (NULL == p)
        {
            return NULL;
        }
    
        p->table = (struct kv **)malloc(MAX_TABLE_SIZE * sizeof(struct kv *));
        if (NULL == p->table)
        {
            free(p);
            return NULL;
        }
    
        memset(p->table, 0, MAX_TABLE_SIZE * sizeof(struct kv *));
    
        return p;
    }
    

    第二步,哈希函数,关于哈希函数我不太了解,因此不做过多阐述,有兴趣的可自行查找资料。总之,它的作用就是将不同key映射成不同的hash值。

    static unsigned int hash_33(char* key)
    {
        unsigned int hash = 0;
        while (*key)
        {
            hash = (hash << 5) + hash + *key++;
        }
        return hash;
    }
    

    第三步,插入函数

    int hash_table_put(hashTable *htable, char *key,  void *value, void (*free_value)(void *))
    {
        int i = hash_33(key) % MAX_TABLE_SIZE;  // 计算hash值
        struct kv *p = htable->table[i];
        struct kv *prev = p;
    
        while (p != NULL)  // 不同key有可能是同一个hash值,所以需要遍历该节点指向的链表
        {
            if (0 == strcmp(p->key, key)) // 已存在此节点,删除原来信息,再指向新信息
            {
                if (p->free_value != NULL)
                {
                    p->free_value(p->value);
                }
                p->value = value;
                p->free_value = free_value;
                break;
            }
            else
            {
                prev = p;
                p = p->next;
            }
        }
    
        if (NULL == p) // 此key无对应节点,新增一个
        {
            char *kstr = (char *)malloc(strlen(key) + 1);
            if (NULL == kstr)
            {
                return 1;
            }
    
            struct kv *tmp = (struct kv *)malloc(sizeof(struct kv));
            if (NULL == tmp)
            {
                free(kstr);
                return 2;
            }
    
            strcpy(kstr, key);
            tmp->key = kstr;
            tmp->value = value;
            tmp->free_value = free_value;
            tmp->next = NULL;
    
            if (NULL == prev)
            {
                htable->table[i] = tmp;
            }
            else
            {
                prev->next = tmp;
            }
        }
    
        return 0;
    }
    

    第四步,查找函数。根据key计算出hash值,直接查找对应位置即可。如果该位置下有多个节点,需要遍历。

    void *hash_table_get(hashTable *htable, char *key)
    {
        int i = hash_33(key) % MAX_TABLE_SIZE; // 计算hash值
        struct kv *p = htable->table[i];
    
        while (p != NULL) // 遍历i位置下的所有节点
        {
            if (0 == strcmp(p->key, key)) // 找到,返回value
            {
                return p->value;
            }
            p = p->next;
        }
    
        return NULL;
    }
    

    最后创建的哈希表结构如图
    在这里插入图片描述
    下面是个简单的应用例子

    typedef struct gnode
    {
        char size;
        int age;
        char name[8];
    }gnode_t;
    
    void free_gnode(void *gt)
    {
        if (gt != NULL)
        {
            free(gt);
        }
    }
    
    void show_g_info(gnode_t *gt)
    {
        if (gt != NULL)
        {
            printf("name : %s, age : %d, size : %c \n\n", gt->name, gt->age, gt->size);
        }
    }
    
    int main(void)
    {
    	// 创建哈希表
        hashTable *tableHead = hash_table_create();
        if (NULL == tableHead)
        {
            return -1;
        }
    
        int i = 0;
        for (i=1; i<21; i++)  // 循环插入20个信息
        {
            gnode_t *g = (gnode_t *)malloc(sizeof(gnode_t));
            if (g != NULL)
            {
                g->size = 'a' + i % 6;
                g->age = 18 + i % 8;
                sprintf(g->name, "user%02d", i);
    
                hash_table_put(tableHead, g->name, g, free_gnode);
            }
        }
    
    	// 获取user10 信息
        gnode_t *t = (gnode_t *)hash_table_get(tableHead, "user10");
        show_g_info(t);
    	// 获取user20 信息
        t = (gnode_t *)hash_table_get(tableHead, "user20");
        show_g_info(t);
    
        hash_table_restory(tableHead);
    
        return 0;
    }
    

    执行结果如下

    @server:~/work/testProj/hash$ ./main
    name : user10, age : 20, size : e
    
    name : user20, age : 22, size : c
    
    @server:~/work/testProj/hash$
    

    最后附上 hashtable.c 下载链接 hashtable.c

    展开全文
  • 构建哈希函数的方法 直接地址法 除留余数法 平方取中法 折叠法 数值分析法 二.利用除留余数方法查找图书 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 #define NULLKEY -32768 typedef ...
  • C语言实现哈希链表查找

    千次阅读 2011-09-30 10:47:44
    #include #define HASHSIZE 101 struct nlist { /*table entry*/ struct nlist *next; /*next entry in chain */ char *name; /* define
  • C语言实现哈希表(链式法)

    千次阅读 多人点赞 2019-11-23 13:13:03
    笔者最近学习数据结构中的哈希表,并用C语言简单实现了。 当然源代码多有参考,此博客旨在交流心得 哈希表原理 结构体说明如下 源代码如下: #include<stdio.h> #include<stdlib.h> #define ...
  • 百度百科-哈希表 一、实现哈希表的主要思路 1、哈希表分为两个过程,一是将数据存入哈希表中,二是在哈希表查找数据(这也是哈希表实现的主要功能——哈希查找) 2、首先我们拥有一组数据(value),需要通过计算找...
  • C语言实现哈希查找表相关操作
  • 大家好,我是练习编程时长两年半的昆工第一ikun,今天我们来分享查找算法中的一个——哈希查找哈希查找适用于有庞大的数据量时的查找,是一种很好用的查找算法,话不多说,开团!!!
  • C语言中, 标准库没有提供哈希表, 哈希表有多种实现方式,可参考以下实现—— 以下哈希表结构为 : 指定长度的哈希表长度,冲突的节点使用延展链表存储数据(后面统一称为冲突链表) 一、基本结构体定义 1、存储数据...
  • 任务:针对某个集体(比如你所在的班级)中的“姓名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。 要求:假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的...
  • C语言实现哈希函数

    2022-08-17 21:12:53
    在除留取余基础上使用线性探测或者二次探测解决冲突的哈希函数(包括计算ASL)C语言实现
  • 代码如下:/* 数据结构C语言哈希表 */#include <stdio>#include <malloc>#define NULLKEY 0 // 0为无记录标志 #define N 10 // 数据元素个数 typedef int KeyType;// 设关键字域为整型 typedef struct{ Key...
  • 哈希查找.zip,哈希查找,Hash.c,document,dictionary.txt
  • C语言哈希表

    千次阅读 2021-11-21 10:01:06
    只要给出关键字的值,我们就可以计算出该关键字在哈希表中的存储位置,方便查找。 冲突:两个或多个不同的关键字根据函数关系计算得到的存储位置一致。关键字个数大于存储位置的个数,就不可避免产生冲突,所以我们...
  • 哈希表C语言实现)超级简洁版

    千次阅读 2022-03-16 23:06:22
    数据结构设计 //字典类型 #define DICT_TYPE_INT 0 #define DICT_TYPE_STR 1 //键值对 typedef struct dict_entry ... //哈希函数 unsigned int (*hash)(void* key); // table 数组存放 dict_entry 指针
  • C语言实现哈希查找

    千次阅读 多人点赞 2018-03-31 22:51:03
    //哈希查找的主要过程是如何建立以哈希表及如何解决元素位置占用的问题;/* 建立哈希表: 首先需要初始化哈希表,并且确实哈希表的长度; 并且根据(数据)%(哈希表长度)计算出数据在哈希表中的位置; 解决...
  • C语言实现散列表(哈希Hash) 实例代码: //散列表查找算法(Hash) #include #include #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define SUCCESS 1 #define UNSUCCESS 0 #define HASHSIZE...
  • C语言简单的创建哈希表

    千次阅读 2022-02-17 20:00:36
    哈希表是根据关键字和值(Key value)而直接进行访问的数据结构,所以需要使用结构体来将之关联。采用结构体指针进行动态内存...可以通过用户的输入来动态创建哈希表进行显示、查找,并通过插入和删除的顺序改变哈希表
  • 哈希表实现---C语言

    2021-07-11 14:45:03
    * 程序名:hash.c,此程序演示哈希表实现,数据元素单链表带头结点。 * 作者:jack 日期:20210711 * 参考作者:C语言技术网(www.freecplus.net), B站UP主:C语言技术网 */ #include <stdio.h> #include ...
  • 哈希表C语言实现

    2020-12-21 15:56:34
    说到哈希表,首先就得说到哈希函数,哈希函数是用来得到给定key值的在哈希表中的存储位置的。哈希函数也并不是固定的,可以自己根据情况来定,一般常用常见的有直接定制法,除留余数法,平方取中法,折叠法,随机数...
  • 主要是练习一个哈希表的框架结构,要注意的是每个哈希表里的数据都要写在链表中,需要用malloc来定义,不然之后free会遇到无法释放的问题。 #include <stdio.h> #include <stdlib.h> #include <...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,437
精华内容 7,374
热门标签
关键字:

c语言实现哈希表查找