散列表是一种空间换时间的数据结构,在算法中提升效率的一种常用的方法。但是,正如其特点,有时候所消耗的空间,真让人头疼,用的时候在二者之间权衡。
散列表,又叫哈希表(HashTable),是能够通过给定的关键字的值直接访问到具体对应值的数据结构。也就是说,把关键字映到一个表中的位置来直接访问记录,以加快访问速度。
通常,我们通过Key来找Value,也就是说,通过Key访问一个映射表来得到Value的地址。而这个映射表,也叫作散列函数或者哈希函数,存放记录的数组叫做散列表。
如果可以通过不同的Key访问到同一个Value,那么就发生了碰撞,我们需要的是通过一个Key可以访问到唯一的Value。
常用的处理冲突的方法有:
开放地址法(开放寻址法)
就是当这个key通过哈希函数找到存放value地址的位置,当这个位置已经存放数据,就存在其紧跟着后面没有占用的位置,如果超过了最大长度,对最大长度取余,这里移动的地址是产生冲突的偏移量。
再哈希法
产生冲突后,用关键字其他部分继续计算地址,直到不产生冲突,当这种方法增加了时间。
链地址法
当产生冲突,把处于同一地址的数据做成一个链表,这种方法最常见。
建立公共溢出区
建立一个公共溢出区,把产生冲突的新地址放在这个公共溢出区里。
###散列表的特点:
访问速度快
由于散列表有散列函数,把Key映射到一个地址上,访问key对映的Value时候,不需要查找,直接跳到那个地址,因此,散列表的增删改查等任何操作,速度都比较快。
需要额外的空间
当发生冲突,需要额外的空间去存储,空间换时间,有舍才有得。
无序
为了快速找到访问的元素,根据散列函数直接找到存储地址,访问速度就快起来,但是有序访问没有办法实现。
可能产生碰撞
没有完美的散列函数,无论如何总会产生冲突,采用冲突的处理办法,就会使散列表变得更加复杂。
下面展示如何实现一个散列表,这里用数组代替散列表元素(在在真实情况下,大多数语言的实现中,大多数元素都是一个特别的数组,每个元素对应一个地址),每个数组元素作为一个地址。
|
|
|
|
|
|