5、散列表

散列表

1、散列函数

简单理解,散列函数就是“将输入映射到数字” 。它满足一些要求:
它应将相同的输入映射到相同的数字,即它必须是一致的。
它应将不同的输入映射到不同的数字。
它具有以下特性:

散列函数总是将同样的输入映射到相同的索引。
散列函数将不同的输入映射到不同的索引。
散列函数知道数组有多大,只返回有效的索引。

 

2、冲突

 

3、时间复杂度

在散列表中查找所花费的时间为常量时间。

 

 

4、性能

要避免冲突,需要有:
较低的填装因子;
良好的散列函数。

  • 填装因子

填装因子大于1意味着商品数量超过了数组的位置数。一旦填装因子开始增大,你就需要在散列表中添加位置,这被称为调整长度( resizing)(通常将数组增长一倍 ) 

  • 良好的散列函数

良好的散列函数让数组中的值呈均匀分布。

糟糕的散列函数让值扎堆,导致大量的冲突。 

 散列函数的结果必须是均匀分布的,这很重要。它们的映射范围必须尽可能大。最糟糕的散列函数莫过于将所有输入都映射到散列表的同一个位置。 

 

5、代码示例

 1 import random
 2 import re
 3 from prettytable import PrettyTable
 4 
 5 # 散列函数(按开头字母分类)
 6 def hashClassfication(phoneBook):
 7     hashPhone = {}
 8     for k,v in phoneBook.items():
 9         if k[0] in hashPhone.keys():
10             # 更新字典
11             hashPhone[k[0]].update({k:v})
12         else:
13             hashPhone[k[0]] = {k:v}
14     return hashPhone
15 
16 # 电话搜索
17 def searchPhone(phoneBook):
18     tb = PrettyTable()
19     tb.field_names = ["\033[1m姓名","电话号码\033[0m"]
20     phoneBook = hashClassfication(phoneBook)
21     choice = input("search..")
22     # 把keys转成列表
23     keysList = list(phoneBook.keys())
24     if choice[0] in keysList:
25         # 长度为1,按字母检索
26         if len(choice) == 1:
27             for k,v in phoneBook.get(choice).items():
28                 tb.add_row([k,v])
29             print(tb)
30         # 按人名检索
31         else:
32             keysList = list(phoneBook.get(choice[0]).keys())
33             results = []
34             for item in keysList:
35                 if re.findall("%s.*" % choice,item):
36                     results.append(item)
37             for item in results:
38                 tb.add_row([item,phoneBook.get(choice[0])[item]])
39             print(tb)
40     else:
41         print("None")
42 
43 if __name__ == '__main__':
44     phone = []
45     for i in range(15):
46         temp = " "
47         for i in range(11):
48             temp += str(random.randint(0,9))
49         phone.append(temp)
50     phoneBook = {
51         "jack":phone[0],
52         "lucy":phone[1],
53         "smith": phone[2],
54         "damin": phone[3],
55         "tom": phone[4],
56         "boss": phone[5],
57         "labor": phone[6],
58         "jason": phone[7],
59         "tony": phone[8],
60         "lili": phone[9],
61         "mike":phone[10],
62         "honey":phone[11],
63         "biden": phone[12],
64         "trump": phone[13],
65         "abort":phone[14]
66     }
67     searchPhone(phoneBook)

 

6、小结

散列表是一种功能强大的数据结构,其操作速度快,还能让你以不同的方式建立数据模型。

你可以结合散列函数和数组来创建散列表。
冲突很糟糕,你应使用可以最大限度减少冲突的散列函数。
散列表的查找、插入和删除速度都非常快。
散列表适合用于模拟映射关系。
一旦填装因子超过0.7,就该调整散列表的长度。
散列表可用于缓存数据(例如,在Web服务器上)。
散列表非常适合用于防止重复。

 

7、应用场景

模拟映射关系(电话簿的查找);
防止重复;
缓存/记住数据,

posted @ 2020-10-31 15:41  Dammond  阅读(119)  评论(0)    收藏  举报