您的位置:首页 > 编程语言 > Python开发

算法导论程序25--散列表(Python)

2017-05-26 09:18 357 查看
在直接寻址方式下,具有关键字k的元素被存放在槽k中。在散列方式下,该元素存放在槽h(k)中:即利用散列函数(hash function)h,由关键字k计算出槽的位置。

这里,函数h将关键字的全域U映射到散列表(hash table)T[0...m-1]的槽位上:

h:U->{0,1,...,m-1}

这里,散列表的大小m一般要比|U|小得多。我们可以说一个具有关键字k的元素被散列到槽h(k)上,也可以说h(k)是关键字k的散列值。



冲突:两个关键字可能映射到同一个槽中。解决冲突的方法:

链接法。开放寻址法。

通过链接法解决冲突:

把散列在同一个槽中的所有元素都放在一个链表中,槽j中有一个指针,它指向存储所有散列到j的元素的链表的表头;如果不存在这样的元素,则槽j中为NIL。

class chained_hash:
def __init__(self,T=[],size=0):
if len(T)==0:
self.T=[None for i in range(size)]
else:
self.T=T
self.size=size
def search(self,k):
if self.T[self.hash_h(k)]!=None:
x=self.T[self.hash_h(k)].list_search(k)
return x
return None
def insert(self,x):
if self.T[self.hash_h(x.key)]==None:
self.T[self.hash_h(x.key)]=DoublyLinkedList(x)
else:
self.T[self.hash_h(x.key)].list_insert(x)
def delete(self,x):
self.T[self.hash_h(x.key)].list_delete(x)
def hash_h(self,key):
return key%12

class Node:
def __init__(self,key):
self.key=key

#####双向链表####
class DoublyNode:
def __init__(self,n_prev,n_next,key):
self.prev=n_prev
self.next=n_next
self.key=key

class DoublyLinkedList:
def __init__(self,head):
self.head=head
def list_search(self,k):
x=self.head
while x !=None and x.key!=k:
x=x.next
return x
def list_insert(self,x):
x.next=self.head
if self.head != None:
self.head.prev=x
self.head=x
x.prev=None
def list_delete(self,x):
if x.prev!=None:
x.prev.next=x.next
else:
self.head=x.next
if x.next !=None:
x.next.prev=x.prev
运行结果:
>>> T=[]
>>> x=DoublyNode(None,None,13)
>>> ch=chained_hash(T,12)
>>> ch.insert(x)
>>> x=DoublyNode(None,None,25)
>>> ch.insert(x)
>>> y=ch.search(25)
>>> y.key
25
>>> ch.delete(y)
>>> ch.T[1].head
<__main__.DoublyNode object at 0x038E8890>
>>> ch.T[1].head.key
13
>>> ch.T[1].head.next
>>> hash_h是自定义的除法散列法。h(k)=k mod m
其中m=12。相应地,散列表的槽T的个数为12。T中的每个元素都是一个双向链表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: