【哈希表】学习记录加代码实现

在数据结构和算法的学习中都要一个词叫做哈希表,今天学习记录一下关于它的知识。

哈希表的概念

散列表(Hash table ,也),是根据键(Key)而直接访问在记忆体储存位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。 这个映射函数称做散列函数,存放记录的数组称做散列表。 一个通俗的例子是,为了查找电话簿中某人的号码,可以创建一个按照人名首字母顺序排列的表(即建立人名.x {displaystyle x}. 到首字母。 F(x) {displaystyle F (x)}. 的一个函数关系),在首字母为W的表中查找“王”姓的电话号码,显然比直接查找就要快得多。
在他的使用中一般涉及两个操作,
1.向哈希表中插入一个关键字:哈希函数决定该关键字的对应值应该存放到表中的哪个区块,并将对应值存放到该区块中
2.在哈希表中搜索一个关键字:使用相同的哈希函数从哈希表中查找对应的区块,并在特定的区块搜索该关键字对应的值

哈希函数

刚开始介绍时,出现了怎样查找王姓的电话号码,我们可以简单的把它用w字母开头进行存储,这样在查找的时候就可以方便快捷的找到。在上述过程中,王” 姓用首字母存储标记就体现了哈希函数的思想。它的官方解释是:将哈希表中元素的关键键值映射为元素存储位置的函数
函数创建规则由原理可知是由一定要求的:

哈希函数应该易于计算,并且尽量使计算出来的索引值均匀分布,这能减少哈希冲突
哈希函数计算得到的哈希值是一个固定长度的输出值
如果 Hash(key1) 不等于 Hash(key2),那么 key1、key2 一定不相等
如果 Hash(key1) 等于 Hash(key2),那么 key1、key2 可能相等,也可能不相等(会发生哈希碰撞)

由于它是用来快速查找用的,所以会用来处理很多种数据,包括整数型、浮点数、字符串类型。关于整数类型的关键字,通常用到的哈希函数方法有:直接定址法、除留余数法、平方取中法、基数转换法、数字分析法、折叠法、随机数法、乘积法、点积法等。

哈希冲突

在上述的哈希函数创造规则时,大家就能发现,有可能Hash(key1)=Hash(key2),即键值不同时得到的索引值是相同的,这样存储或者查找就会撞车。这就是哈希冲突出现了。
解决哈希冲突的方法,主流是由两种方法,
1.开放地址法:指的是将哈希表中的「空地址」向处理冲突开放。当哈希表未满时,处理冲突时需要尝试另外的单元,直到找到空的单元为止。通俗的来说就是你占了地方,那么我去换一个地方存。
2.链地址法:将具有相同哈希地址的元素(或记录)存储在同一个线性链表中。 链地址法是一种更加常用的哈希冲突解决方法。通俗的理解就是我们通用一个地址,然后我们用链表的形式手拉手占用这个索引值。

哈希表的代码实现

代码我是找的别人的:

class Hash_Table(object):
    def __init__(self):
        self.size = 11
        self.slots = [None] * self.size
        self.val = [None] * self.size

    def hash_function(self,key):
        return key % self.size

    def rehash(self,oldhash):
        return (oldhash + 1) % self.size

    def add(self, key, val):
        hash_value = self.hash_function(key)
        if self.slots[hash_value] == None:
            self.slots[hash_value] = key
            self.val[hash_value] = val
        else:
            if self.slots[hash_value] == key:
                self.val[hash_value] = val
            else:
                nextslot = self.rehash(hash_value)
                while self.slots[nextslot] != None and self.slots[nextslot] != key:
                    nextslot = self.rehash(nextslot)
                if self.slots[nextslot] == None:
                    self.slots[nextslot] = key
                    self.val[nextslot] = val
                else:
                    self.data[nextslot] = val

    def get(self, key):
        startslot = self.hash_function(key)
        val = None
        stop = False
        found = False
        position = startslot
        while self.slots[position] != None and not found and not stop:
            if self.slots[position] == key:
                found = True
                val = self.val[position]
            else:
                position = self.rehash(position)
                if position == startslot:
                    stop = True
        return val

    def __getitem__(self, key):
        return self.get(key)

    def __setitem__(self, key, val):
        self.add(key,val)

哈希表(hash table)—python实现

你可能感兴趣的:(算法学习,笔记,日常分享,python,哈希算法,算法)