这几天用在写代码(实际上是为了补作业)的时间明显比以前多了,在这过程中也
发现了自己由于前期的训练太少,导致很多基础的语法都不熟悉,有很长的时间都用在了debug上。很多问题写的时候记得,过后又忘了,下次又再错,所以要找个地方记录下来。命名以及代码的规范还有待加强,说到底,还是写得少见得少
一、问题描述及要求
Description
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
本题请使用散列函数:除留余数法(取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址)建立哈希表,并判断给定值是否在散列表中。
注意:本题请考虑冲突情况,即碰撞。本题请使用链冲突法解决冲突,即散列到相同地址后以建立子链的方式解决元素冲突,因此本题不考虑总元素大于散列表大小而溢出的情况。重复元素只存一个。
Input
第一行数字表示要建立的散列表的大小,第二行表示要作为元素建立散列表的整数序列(注意:元素之间以空格分开,第一行散列表大小并不表示本行元素的数量),第三行表示要插入元素的数量n,接下来n行表示待插入元素值;下一行表示要删除元素的数量m,接下来m行表示待删除元素值;下一行表示要查找元素的数量r,接下来r行表示待查找元素值。
Output
插入无输出,对于每个待删除元素,元素若在散列表中,删除即可,若不在则输出 ‘Delete Error’,注意单词间空格;执行完插入删除后,查找元素是否在散列表中,若在则在相应行输出True, 否则输出False。
二、代码
class Node(object):
def __init__(self,value=None,pnext=None):
self.value=value
self._next=pnext
class HashTable:
"""建立哈希表时需要输入他的长度"""
def __init__(self,size=10):
self.size=size
self.slots=[Node()]*self.size
"""初始化表头"""
def hash_funt(self,key):#散列函数
return key%self.size
def append(self,key):
"""找到元素的位置"""
hash_value=self.hash_funt(key)
now_slot=self.slots[hash_value]
"""冲突处理"""
if now_slot.value==None:#第一个位置还没开始存放,此时没有冲突
self.slots[hash_value]=Node(key)
else:
if key!=now_slot.value:#如果不是重复值
"""遍历到最后一个位置或者是到达相同值的位置"""
while now_slot._next is not None and key !=now_slot._next.value:
now_slot=now_slot._next
"""判断最后一个元素是否和key相等"""
if now_slot._next is None:
now_slot._next=Node(key)
"""删除元素"""
def delslot(self,key):
hash_value=self.hash_funt(key)
now_slot=self.slots[hash_value]
if now_slot.value is not None:#首先判断是否是空的,若为空,则不存在这个数
"""现在开始查找相应的元素"""
if now_slot.value==key:#找到了!!!!
"""判断其后面还有没有元素"""
if now_slot._next==None:
now_slot.value=None
else:
self.slots[hash_value]=now_slot._next#如果下一个不是空的话,就直接指向下一个
else: #第一个元素不是key
"""开始遍历找到对应元素"""
while now_slot._next is not None and key !=now_slot._next.value:
now_slot=now_slot._next
if now_slot._next is not None:
now_slot._next=now_slot._next._next#这里要注意判断是now_slot=now_slot._next._next还是now_slot._next=now_slot._next._next
else:
if key!=now_slot.value:#判断是否找到了需要的值###此处易错点:不要写成now_slot.next.value
print("Delete Error")
else:
now_slot.value=None
else:
print('Delete Error')
def find_slot(self,key):
hash_value=self.hash_funt(key)
now_slot=self.slots[hash_value]
if now_slot.value is not None:#首先判断是否是空的,若为空,则不存在这个数
"""现在开始查找相应的元素"""
if now_slot.value==key:#找到了!!!!
print('True')
else: #第一个元素不是key
"""开始遍历找到对应元素"""
while now_slot._next is not None and key !=now_slot._next.value:
now_slot=now_slot._next
if now_slot._next is not None:
print('True')
else:
if key!=now_slot.value:#判断最后一个是否是需要的值
print("False")
else:
print('True')
else:
print('False')
if __name__ == "__main__":
#N为要建立的Hash Table的大小
N= int(input())
myhash = HashTable(N)
#初始化一个Hash table
temp = [int(x) for x in input().split()]#类型转换
#print(temp)测试用代码,判断类型转换是否成功
for i in temp:
myhash.append(i)
#插入
m = int(input())
for i in range(m):
k=int(input())
myhash.append(k)
#删除
num = int(input())
for i in range(num):
k=int(input())
myhash.delslot(k)
#查找
j = int(input())
for i in range(j):
numl = int(input())
myhash.find_slot(numl)
三、遇到的难题
个人觉得难点还是在链表上,_next 的位置真的让我纠结了好久好久。写的时候其实还有很多其他比较小的细节错误,但是现在想不起来了。自己的理解都写在了注释里,便于自己能更好的理解这东拼西凑来的代码。下次写完后及时的反馈在文章里,这样就能更清楚的发现自己的问题了。
这个是第一篇,就到这里了