哈希表 学习

看了几篇文章,主要意思就是用简单的值index,去索引复杂的值key,进而找到想要的值value.

哈希算法主旨:index  = f(key)

数据存放格式:(key.value)

但是存在问题是,

1.哈希算法使不同的key产生相同的index

2.分配给哈希表的内存满了之后,整个哈希表的迁移太累赘了。

针对第一个问题,下面介绍两个方案:

拉链法:http://www.cnblogs.com/xiekeli/archive/2012/01/13/2321207.html

相同index的键值对,就用链表往后去存储。

typedef struct _node{
      char *key;
      char *value;
      struct _node *next;
}node;

#define HASHSIZE 101
static node* hashtab[HASHSIZE];  //hash index

哈希桶:http://www.cnblogs.com/xiekeli/archive/2012/01/16/2323391.html

struct Pair {
    char *key;
    char *value;
};

struct Bucket {
    unsigned int count;
    Pair *pairs;
};

struct StrMap {
    unsigned int count;
    Bucket *buckets;
};

首先哈希桶的个数是固定的,有用户构建的时候输入,一旦构建,个数就已经固定;查找的时候首先将key值通过哈希函数获取哈希值,根据哈希值获取到对应的哈希桶,然后遍历哈希桶内的pairs数组获取;


这两种实现方法看似比较类似,但也有差异:

基于哈希桶的情况下,由于Hash桶容量的限制,所以,有可能发生Hash表填不满的情况,也就是,虽然Hash表里面还有空位,但是新建的表项由于冲突过多,而不能装入Hash表中。不过,这样的实现也有其好处,就是查表的最大开销是可以确定的,因为最多处理的冲突数是确定的,所以算法的时间复杂度为O(1)+O(m),其中m为Hash桶容量。

而另一种通过链表的实现,由于Hash桶的容量是无限的,因此,只要没有超出Hash表的最大容量,就能够容纳新建的表项。但是,一旦发生了Hash冲突严重的情况,就会造成Hash桶的链表过长,大大降低查找效率。在最坏的情况下,时间复杂度退化为O(n),其中n为Hash表的总容量。当然,这种情况的概率小之又小,几乎是可以忽略的。

 比较好的代码:

http://blog.csdn.net/smstong/article/details/51145786

联我:shen5773384##163.com
原文地址:https://www.cnblogs.com/WMCH/p/8288124.html