散列函数是这样的函数,即无论你给它什么数据,它都还你一个数字。
如果用专业术语来表达的话,我们会说,散列函数“将输入映射到数字”。你可能认为散列函数输出的数字没什么规律,但其实散列函数必须满足一些要求。
- 它必须是一致的。例如,假设你输入apple时得到的是4,那么每次输入apple时,得到的都必须为4。如果不是这样,散列表将毫无用处。
- 它应将不同的输入映射到不同的数字。 例如, 如果一个散列函数不管输入是什么都返回1,它就不是好的散列函数。最理想的情况是,将不同的输入映射到不同的数字。
散列函数将输入映射为数字,这有何用途呢?你可使用它来打造你的“ Maggie”!
为此,首先创建一个空数组。
你将在这个数组中存储商品的价格。下面来将苹果的价格加入到这个数组中。为此,将apple作为输入交给散列函数。
散列函数的输出为3,因此我们将苹果的价格存储到数组的索引3处。
下面将牛奶(milk)的价格存储到数组中。为此,将milk作为散列函数的输入。
散列函数的输出为0,因此我们将牛奶的价格存储在索引0处。
不断地重复这个过程,最终整个数组将填满价格。
现在假设需要知道鳄梨(avocado)的价格。你无需在数组中查找,只需将avocado作为输入交给散列函数。
它将告诉你鳄梨的价格存储在索引4处。果然,你在那里找到了。
散列函数准确地指出了价格的存储位置,你根本不用查找!之所以能够这样,具体原因如下。
- 散列函数总是将同样的输入映射到相同的索引。每次你输入avocado,得到的都是同一个数字。因此,你可首先使用它来确定将鳄梨的价格存储在什么地方,并在以后使用它来确定鳄梨的价格存储在什么地方。
- 散列函数将不同的输入映射到不同的索引。 avocado映射到索引4, milk映射到索引0。每种商品都映射到数组的不同位置,让你能够将其价格存储到这里。
- 散列函数知道数组有多大,只返回有效的索引。如果数组包含5个元素,散列函数就不会返回无效索引100。
在你将学习的复杂数据结构中,散列表可能是最有用的,也被称为散列映射、映射、字典和关联数组。散列表的速度很快!还记得第2章关于数组和链表的讨论吗?你可以立即获取数组中的元素,而散列表也使用数组来存储数据,因此其获取元素的速度与数组一样快。
你可能根本不需要自己去实现散列表,任一优秀的语言都提供了散列表实现。 Python提供的散列表实现为字典,你可使用函数dict来创建散列表。
>>> book = dict()
创建散列表book后,在其中添加一些商品的价格。
>>> book["apple"] = 0.67
>>> book["milk"] = 1.49
>>> book["avocado"] = 1.49
>>> print book
{'avocado': 1.49, 'apple': 0.67, 'milk': 1.49}
非常简单!我们来查询鳄梨的价格。
>>> print book["avocado"]
散列表由键和值组成。在前面的散列表book中,键为商品名,值为商品价格。散列表将键映射到值。
在下一节中,你将看到一些散列表使用示例。