Python中常用的数据结构---哈希表(字典)

Python中常用的数据结构—哈希表(字典)

常用的数据结构有数组、链表(一对一)、栈和队列、哈希表、树(一对多)、图(多对多)等结构。
在本目录下我们将讲解,通过python语言实现常用的数据结构。

4.哈希表

哈希表(hash table)也叫作散列表,这种数据结构提供了键(key)和值(value)的映射关系。只要给出一个key,就可以高效查找到它所匹配的value,时间复杂度接近于O(1)。
哈希函数就是将key和value值对应起来的函数。在不同语言中,哈希函数的实现方式是不一样的,在python语言中,哈希表对应的集合叫做字典(dict)
在python和大多数面向对象的语言中,每一个对象都有属于自己的hash值,这个hash值是区分不同对象的重要标识。无论对象自身的类型是什么,它们的hash值都是一个整型变量。
既然都是整型变量,想要转化成数组的下标也就不难实现了。最简单的转化方式是按照数组长度进行取模运算

index = hash(key) % size

实际上,python中的哈希函数并没有直接采用取模运算,而利用了位运算的方式来优化性能。不过这里我们姑且把它简单理解成取模操作。
通过hash函数,可以把字符串或其他类型的key,转化成数组的下标index。

比如给出长度为8的数组,则当
key = 001121时,
index = hash(“001121”) % size = 1420036703 % 8 = 7
而当key = "this"时,
index = hash(“this”) % size = 3559070 % 8 = 6

4.1哈希表的写操作(put)
例如调用dict[“002931”] = “王五”,意思是插入一组002931、value为王五的键值对。
第一步,通过哈希函数,把key转化成数组下标index(比如5)
第二步,如果数组下标5对应的位置没有元素,就把value值填充到数组下表为5的位置。
注意:由于数组的长度是有限的,当插入的value值越来越多时,不同的key通过哈希函数获得的下标有可能是相同的。例如,002936这个key对应的数组下标是2;002947这个key对应的数组下标也是2。则此时这种情况叫做“哈希冲突”。
哈希冲突是无法避免的,既然不能避免,就要想办法解决。解决的办法主要有两种:开放寻址方法,链表法。
4.2哈希表的读操作(get)
例如调用dict[“002936”],意思是查找key为002936的Entry在哈希表中所对应的值。
第一步,通过哈希函数,把key转化成数组下标index(比如2)
第二步,找到数组下标2所对应的元素,如果这个元素的key是002936,那么找到了;如果这个key不是002936,那么由于数组的每个元素都与一个链表对应,则可以顺着链表慢慢往下找,看看是否与key相匹配的节点。
在众多编程语言中,有些语言的哈希表采用链表法,最具代表性的就是Java中HashMap;有些编程语言采用的是开放寻址法,比如python中的dict。
重点:哈希表可以说是数组和链表的结合,在算法应用中很普遍。

小结:

(1)数组:数组是由有限个相同类型的变量所组成的有序集合,它的物理存储方式是顺序存储,访问方式是随机访问。利用下表查找数组元素的时间复杂度是O(1),中间插入、删除数组元素的时间复杂度是O(n)。
(2)链表:链表是一种链式数据结构,由若干节点组成,每个节点包含指向下一节点的指针。链表的物理存储方式是随机存储,访问方式是顺序访问。查找链表节点的时间复杂度是O(n),中间插入、删除节点的时间复杂度是O(1)。
(3)栈:栈是一种线性逻辑结构,可以用数组实现,也可以用链表实现。栈包含入栈和出栈操作,遵循先入后出的原则。
(4)队列:队列也是一种线性逻辑结构,可以用数组实现,也可以用链表实现。队列包含入队和出队操作,遵循先入先出的原则。
(5)哈希表:哈希表也叫作散列表,是存储 key-value映射的集合。对于某一个key,哈希表可以在接近O(1)的时间复杂度内进行读写操作。哈希表通过哈希函数实现key和数组下标的转换,通过开放寻址法和链表法来解决哈希冲突。

你可能感兴趣的:(python常用数据结构,数据结构,散列表,哈希算法)