定义: 哈希表是一种数据结构,它是指一种由数组存储链表头部的表。我们根据哈希函数来对数据进行映射,从而把数据分配到这个表的不同链表中。这么做的目的是因为,单个链表进行查找效率很低,你只能逐一查找。而通过哈希函数分配到不同链表后,你只需要再从那个比较小的链表中进行查找。能够大大的提高查找效率。因此,判断哈希函数的好坏主要看能否把数据均匀分配到不同链表中,尽量不能出现大量数据聚集到同一链表的情况。
示意图
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。这是另一种说法,其实是同一种东西。
具体问题:
google公司的一个上机题:
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址…),当输入该员工的id时,要求查找到该员工的 所有信息.
要求:
- 不使用数据库,速度越快越好=>哈希表(散列)
- 添加时,保证按照id从低到高插入 [思考:如果id不是从低到高插入,但要求各条链表仍是从低到高,怎么解决?]
- 使用链表来实现哈希表, 该链表不带表头
代码实现:
#哈希表保存雇员信息
'''
1、一个数组,里面存储着链表,链表存储雇员信息
2、也就是说数组里面实际存储着链表的头节点
3、定义雇员结构{id,name,address},即链表的结点
4、链表[]
5、HashTab[]
6、散列函数
'''
class Emp(object):
def __init__(self,ID,name):
self.ID = ID
self.name=name
self.next=None
def show(self):
print('雇员信息:'+str(self.ID)+' '+self.name)
class LinkedList(object):
def __init__(self):
self.head=None
#添加雇员
def add(self,emp):
if self.head==None:
self.head=emp
return
curEmp = self.head
while True:
if curEmp.next==None:
break
curEmp=curEmp.next
curEmp.next=emp
#寻找雇员,找到后返回emp,否则返回None
def finEmp(self,ID):
if self.head == None:
return None
curEmp = self.head
while(True):
if curEmp.ID == ID:
break
if curEmp.next == None:
curEmp=None
break
curEmp = curEmp.next
return curEmp
#显示雇员
def showlist(self,no):
if self.head==None:
print("链表{}为空!".format(no))
return
print('链表{}的信息为:'.format(no))
curEmp = self.head
while True:
print('=> id={} name={} '.format(curEmp.ID,curEmp.name))
if curEmp.next==None:
break
curEmp = curEmp.next#后移遍历
class HashTab(object):
def __init__(self,size):
self.arr = [LinkedList() for i in range(size)]
self.size = size
def hashFun(self,ID):
return ID % self.size
def add(self,emp):
#根据雇员的id进行哈希,进而分配到不同的链表
arrNo = self.hashFun(emp.ID)
#将emp添加到对应的链表中
self.arr[arrNo].add(emp)
def lookAll(self):
for i in range(self.size):
self.arr[i].showlist(i+1)
#根据输入遍历hashTab
def findEmp(self,ID):
empNo = self.hashFun(ID)
emp = self.arr[empNo].finEmp(ID)
if emp!=None:
print('在第{}条链表中找到该雇员 name = {}'.format(empNo+1,emp.name))
return emp
else:
print('在哈希表中没有找到该成员~')
emp1 = Emp(11,'肖茵')
emp2= Emp(672,'刘伟')
emp3= Emp(23,'王五')
emp4= Emp(42,'李四')
emp5= Emp(45,'张三')
haxi = HashTab(3)
while(True):
print()
key = input('add:添加雇员\nfind:查找雇员\nlist:显示雇员\nexit:退出系统\n')
if key=='add':
ID = int(input('ID = '))
name = input('name = ')
emp = Emp(ID,name)
haxi.add(emp)
elif key=='list':
haxi.lookAll()
elif key=='find':
ID = int(input("ID = "))
haxi.findEmp(ID)
elif key=='exit':
print('退出成功')
break