美文网首页
HASH表的原理和实现

HASH表的原理和实现

作者: define南拳 | 来源:发表于2017-11-07 08:40 被阅读0次

哈希表的原理

哈希表的存储原理

什么是哈希?

哈希相当于一个人的名字,可以通过名字可以找到这个人

什么是哈希碰撞?

假设一个班级里边有50个人,有两个人的名字都叫张成荣,那么这就是哈希碰撞

为什么会出现哈希碰撞?

假设对于一段文字进行哈希运算,得到的哈希值是123456789

对于另外一段文字进行哈希运算,也可能得到哈希值是123456789

深层原因体现了哈希算法的局限性

哈希的用法

举个例子:

一个学校有40个班级

每个班级平均30个人

那么查找张成荣这个人应该如何查找呢?

传统思维:

两层for循环嵌套

哈希思维:

每个学生入校的时候,对这个人的名字进行哈希运算,得到哈希值123456789

对哈希值进行40的模除运算

得到1~40的结果

结果为1的去1班,为2的去2班

那么查找的时候,就可以首先对张成荣进行哈希和模除运算,得到张成荣所在的班级,然后再在班里边进行名字的比对查找,提高效率

哈希的实例用法(NSDictionary的c语言实现):

hash_map.h头文件

//

//hash_map.h

//hash_map

/**

NSDictionary的c语言实现

**/

//Created by rong on 2017/11/5.

//Copyright © 2017年 zcr. All rights reserved.

//

#ifndef hash_map_h

#define hash_map_h

#include

//哈希链表

structhash_map;

//创建

structhash_map* hash_map_create(void);

//删除map对象

voidhash_map_clear(structhash_map* map);

//添加数据

//keyvalue

voidhash_map_add(structhash_map* map,constchar* key ,void* value);

//删除key

voidhash_map_remove(structhash_map* map,constchar* key);

//获取hashmap中指定key对应的值

void* hash_map_find(structhash_map* map,constchar* key);

//打印hashmap

voidhash_map_print(structhash_map* map);

#endif/* hash_map_h */

hash_map.m文件

//

//hash_map.c

//hash_map

//

//Created by rong on 2017/11/5.

//Copyright © 2017年 zcr. All rights reserved.

//

#include

#include

#include

#include"hash_map.h"

#define HASH_ARRAY_MAX256

#definemy_malloc malloc

#definemy_free free

structhash_node{

charkey[64];

void* value;

structhash_node* next;//指向下一个hash节点的指针

};

structhash_map{

structhash_node* hash_array[HASH_ARRAY_MAX];

};

#pragma mark - hash_node

staticstructhash_node* hash_node_create(char* key,void* value){

structhash_node* node = (structhash_node*)my_malloc(sizeof(structhash_node));

memset(node,0,sizeof(structhash_node));

strcpy(node->key, key);

node->value= value;

returnnode;

}

staticvoidhash_node_free(structhash_node* node){

my_free(node);

}

#pragma mark - hash_map

//hash算法

unsignedintSDBMHash(char*str)

{

unsignedinthash =0;

while(*str)

{

// equivalent to: hash = 65599*hash + (*str++);

hash = (*str++) + (hash <<6) + (hash <<16) - hash;

}

return(hash &0x7FFFFFFF);

}

//根据key进行哈希运算,然后模运算获取key值

staticintkey_gethashvalue(char*key){

//哈希

inthash =SDBMHash(key);

//模运算

intkeyhash = hash%HASH_ARRAY_MAX;

returnkeyhash;

}

structhash_map* hash_map_create(void){

structhash_map*map = (structhash_map*)my_malloc(sizeof(structhash_map));

memset(map,0,sizeof(structhash_map));

returnmap;

}

voidhash_map_add(structhash_map* map,constchar* key ,void* value){

intv =key_gethashvalue((char*)key);

//将新的节点加入到map中

structhash_node* newNode =hash_node_create((char*)key, value);

newNode->next= map->hash_array[v];//将新建的node指向原来的头节点

map->hash_array[v]=newNode;//头节点指针指向新的指针

return;

}

voidhash_map_remove(structhash_map* map,constchar* key){

intv =key_gethashvalue((char*)key);

structhash_node** walk = &(map->hash_array[v]);

//单链表的删除操作!!!

while(*walk) {

if(strcmp((*walk)->key, (char*)key)==0) {//名字相同

structhash_node*node_remove = *walk;

*walk = node_remove->next;

node_remove->next=NULL;

hash_node_free(node_remove);

}else{

walk = &((*walk)->next);

}

}

}

void* hash_map_find(structhash_map* map,constchar* key){

intv =key_gethashvalue((char*)key);

structhash_node* walk= map->hash_array[v];

while(walk) {

if(strcmp(walk->key, key)) {

returnwalk->value;

}

walk = walk->next;

}

returnNULL;

}

voidhash_map_remove_object_for_key(structhash_map* map,char* key){

intv =key_gethashvalue(key);

structhash_node** walk = &(map->hash_array[v]);

while(*walk) {

if(strcmp((*walk)->key, (constchar*)key)==0) {

//删除节点

structhash_node*tmpnode = *walk;

*walk = tmpnode->next;

tmpnode->next=NULL;

hash_node_free(tmpnode);

}else{

walk = &((*walk)->next);

}

}

}

voidhash_map_clear(structhash_map* map){

//释放所有节点

for(inti =0; i

structhash_node* head = map->hash_array[i];

while(head) {

structhash_node* node =head;

head = node->next;

node->next=NULL;//删除链表节点的时候直接释放这块内存不可以吗,为什么还要指向空呢?

hash_node_free(node);

}

}

memset(map,0,sizeof(structhash_map));

}

voidhash_map_print(structhash_map* map){

for(inti =0; i

structhash_node* head = map->hash_array[i];

while(head) {

structhash_node* node = head;

printf("node key=%s value=%s \n",node->key,(char*)node->value);

head = node->next;

}

}

}

main.h

//

//main.c

//hash_map

/*

NSDictionary的原理和实现

NSDictionary的原理:哈希链表

*/

//Created by rong on 2017/11/5.

//Copyright © 2017年 zcr. All rights reserved.

//

#include

#include"hash_map.h"

intmain(intargc,constchar* argv[]) {

structhash_map* map =hash_map_create();

hash_map_add(map,"name","zhangchengrong");

hash_map_add(map,"bid","com.jalon.test");

hash_map_print(map);

//删除key

hash_map_remove_object_for_key(map,"bid");

hash_map_print(map);

//清空hash表

//hash_map_clear(map);

//hash_map_print(map);

return0;

}

相关文章

  • C Hash表 散列表,又叫哈希表

    1: 理解HASH表的原理,为什么能实现基于名字快速查找;2: 理解HASH算法;3: 编写HASH表; 原理 算...

  • NSDictionary实现原理

    字典原理 NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的, hash...

  • NSDictionary的实现原理

    一、NSDictionary使用原理 hash表来实现key和value之间的映射和存储的,hash函数设计的好坏...

  • HASH表的原理和实现

    哈希表的原理 什么是哈希? 哈希相当于一个人的名字,可以通过名字可以找到这个人 什么是哈希碰撞? 假设一个班级里边...

  • NSDictionary实现原理

    字典原理 NSDictionary(字典)是使用hash表来实现key和value之间的映射和存储的 方法:- (...

  • iOS 字典的实现原理

    一、NSDictionary使用原理 1.NSDictionary(字典)是使用hash表来实现key和value...

  • hash表原理

    一、NSDictionary使用原理 1.NSDictionary(字典)是使用hash表来实现key和value...

  • iOS 字典的实现原理

    一、NSDictionary使用原理1.NSDictionary(字典)是使用hash表来实现key和value之...

  • 哈希表,字典,数组,链表

    1:哈希表 的数据结构,底层实现原理 底层实现:数组 + 链表 哈希表(Hash table,也叫散列表)...

  • 12 - go简单实现hashmap

    注意:还没有解决hash冲突和hash倾斜的问题。 参考: 1.go中map实现的原理 理解Golang哈希表Ma...

网友评论

      本文标题:HASH表的原理和实现

      本文链接:https://www.haomeiwen.com/subject/jwvhmxtx.html