Swift
编程
Swift51.com
首页
社区
▼
资讯
问答
分享
建议
开源代码
Xcode下载
Swift教程
hot
登录
注册
当前位置:
首页
> 分享
欢迎加入QQ讨论群258996829
苹果6袋
6
麦子学院
Php内核中的HashTable相关使用详解
发布时间:2016-12-21 15:42 回复:0 查看:2207 最后回复:2016-12-21 15:42
本文和大家分享的主要是php内核的HashTable相关使用,希望通过本文的分享,对大家
学习php
有所帮助。
typedef struct _Bucket
{
char *key;
void *value;
struct _Bucket *next;
} Bucket;
typedef struct _HashTable
{
int size;
int elem_num;
Bucket** buckets;
} HashTable;
这个是一个简化过的哈希表结构
Bucket是一个链表,而_HashTable用于存储hash值并指向真正的数据储存单位
解决冲突算法DJBX33A
而链表是为了解决冲突用的,冲突解决采用DJBX33A算法,算法的内容如下
inlineunsignedtime33(charconst*str,intlen)
{
unsigned long hash = 5381;
/* variant with the hash unrolled eight times */
for (; len >= 8; len -= 8) {
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
}
switch (len) {
case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 1: hash = ((hash << 5) + hash) + *str++; break;
case 0: break;
}
return hash;
}
HashTable的初始化
初始化,申请空间并且设置初始化值
inthash_init(HashTable *ht)
{
ht->size = HASH_TABLE_INIT_SIZE;
ht->elem_num = 0;
ht->buckets = (Bucket **)calloc(ht->size, sizeof(Bucket *));
if(ht->buckets == NULL) return FAILED;
LOG_MSG("[init]\tsize: %i\n", ht->size);
return SUCCESS;
}
HashTable的插入
插入函数,插入时验证key是否存在,存在更新value值,不存在并取发生冲突则创建新节点并插入到原有链表的头部
inthash_insert(HashTable *ht,char*key,void*value)
{
// check if we need to resize the hashtable
resize_hash_table_if_needed(ht);
int index = HASH_INDEX(ht, key);
Bucket *org_bucket = ht->buckets[index];
Bucket *tmp_bucket = org_bucket;
// check if the key exits already
while(tmp_bucket)
{
if(strcmp(key, tmp_bucket->key) == 0)
{
LOG_MSG("[update]\tkey: %s\n", key);
tmp_bucket->value = value;
return SUCCESS;
}
tmp_bucket = tmp_bucket->next;
}
Bucket *bucket = (Bucket *)malloc(sizeof(Bucket));
bucket->key = key;
bucket->value = value;
bucket->next = NULL;
ht->elem_num += 1;
if(org_bucket != NULL)
{
LOG_MSG("[collision]\tindex:%d key:%s\n", index, key);
bucket->next = org_bucket;
}
ht->buckets[index]= bucket;
LOG_MSG("[insert]\tindex:%d key:%s\tht(num:%d)\n",
index, key, ht->elem_num);
return SUCCESS;
}
HashTable的扩容
当Hash表容量满了的时候,Hash表的性能会下降,这时候需要对Hash表进行扩容
先把原来Hash表容量变成两倍,然后对其进行重新插入操作,时间复杂度为O(n)
staticvoidresize_hash_table_if_needed(HashTable *ht)
{
if(ht->size - ht->elem_num < 1)
{
hash_resize(ht);
}
}
staticinthash_resize(HashTable *ht)
{
// double the size
int org_size = ht->size;
ht->size = ht->size * 2;
ht->elem_num = 0;
LOG_MSG("[resize]\torg size: %i\tnew size: %i\n", org_size, ht->size);
Bucket **buckets = (Bucket **)calloc(ht->size, sizeof(Bucket *));
Bucket **org_buckets = ht->buckets;
ht->buckets = buckets;
int i = 0;
for(i=0; i < org_size; ++i)
{
Bucket *cur = org_buckets
;
Bucket *tmp;
while(cur)
{
// rehash: insert again
hash_insert(ht, cur->key, cur->value);
// free the org bucket, but not the element
tmp = cur;
cur = cur->next;
free(tmp);
}
}
free(org_buckets);
LOG_MSG("[resize] done\n");
return SUCCESS;
}
HashTable的查找
元素的查找和插入采取相同的策略,都是先获得hash值,然后取得bucket链表,随后比较键名进行查找
inthash_lookup(HashTable *ht,char*key,void**result)
{
int index = HASH_INDEX(ht, key);
Bucket *bucket = ht->buckets[index];
if(bucket == NULL) goto failed;
while(bucket)
{
if(strcmp(bucket->key, key) == 0)
{
LOG_MSG("[lookup]\t found %s\tindex:%i value: %p\n",
key, index, bucket->value);
*result = bucket->value;
return SUCCESS;
}
bucket = bucket->next;
}
failed:
LOG_MSG("[lookup]\t key:%s\tfailed\t\n", key);
return FAILED;
}
来源:William的后花园
取消引用
您还未登录,
请先登录
提 问
热门帖子
iDev 全平台开发者大会门票免费送!限量10张!
苹果Mac Pro垃圾桶 最低配的ME253CH
本人想买个苹果电脑搞开发,哪位大侠指点下
求助:failable initializer 'init(name:)' cannot override a non-failable initializer
为庆祝Swift发布1个月,雨燕社区正式上线。
在UITextFeild里输入数据,这个数据怎么做加减乘除?
Swift 高仿喜马拉雅FM
要成为自由职业者?先要学会苹果的Swift哦
关于嵌入式引用\()
用swift实现的调用系统相机,相册的DEMO
Swift 教程
最新帖子
swift_5.3可以更新了
swift如何实现左滑删除
IBM Swift Sandbox访问
Thread 18: Fatal error: 'try!' expression unexpectedly raised an error: Error
跟随手势滑动的ScrollableTextField
Swift5.0什么时候出
什么时候出5.0
PerfectTemplate 无法编译
WWDC19 苹果宣布全新 UI 框架 SwiftUI
水平滚动视图Carousel
Xcode 9.4下载