算法题解第七章

14 篇文章 0 订阅
13 篇文章 0 订阅
文章详细介绍了哈希表(散列表)的概念,包括其线性结构特性、哈希函数的计算、直接寻址表和哈希查询法的优缺点。重点讨论了哈希冲突及其解决方法,如开放寻址法和拉链法,并给出了Python中字典和集合的哈希表实现示例。最后,文章提供了一个简单的拉链法哈希表的类实现。
摘要由CSDN通过智能技术生成

散列表 英文名hash table,也叫哈希表

#它也是一种线性表的存储结构,它是由一个寻址表和一个哈希函数组成
#主要的方法是通过哈希函数来计算数据存储位置,通常是将关键字k作为自变量
#一般都支持insert(key,value)
#get(key),delet(key) 增查删动作

#既然是线性结构的表那么查找方式是不是和链表一样呢?

#第一:直接寻址表
#当我们的key的数量很小的时候,直接寻址是最快的方法-一个一个的算
#比如我们用key 0-10 建立来一个列表[0,1,2,3,4,5,6,7,8,9,10]🇺每个位置都是空的
#那么整块是比较小的直接通过哈希函数计算即可
#缺点也很明显:
#当key的值很大的时候 需要耗费大量的内存来生成对应的空间
#无法处理关键字不是数字的情况

#第二哈希查询法(key为k的元素放到k位置上)
#做法构建大小为m的寻址表T
#key作为k的元素放到哈希函数h(k)位置上-即[0,m-1]
#比如我们现在有这个一个长度为10的哈希表,哈希的函数为h(k)=k%10
#要存储的元素为5,20,11,7
#那么整块的结构为
#[(20),(11),(),(),(),(5),(),(7),(),()]
#[0,1,2,3,4,5,6,7,8,9]

#但是由于哈希表的大小是有限的 而存储的值是无法预计的
#所以对于哈希函数都会出现两个不同元素映射到同一位置
#这种情况叫哈希冲突 比如h(10)=h(20)=h(30)
#解决方法有开放寻址法:如果哈希函数返回的位置已经有值,则可以向后探查新的位置来存储这个值
#线性探查:如果位置x被占用 则探查x+1,x+2
#二次探查:如果位置x被占用,则探查x+(1的平方)或x-(1的平方)
#二度哈希:假如有n个哈希函数,当使用第一个哈希函数发生冲突,则使用第二个哈希函数
#拉链表
#哈希位置存的不是一个元素而是一个链表,这样每次冲突发生的时候,冲突的元素将会被加到该位置链表的最后
#哈希函数一般有h(k)=k%m
#乘法哈希函数
#h(k)=floor(m*(Akey%1))
#全域哈希函数
#ha,b(k)=((a
key+b)mod p)mode m a,b=1,2…,p-1

#python中的主要代表就是字典与集合,通过key,value来存储数据,通过key找到对应数据而不是直接通过下标
#里面能存储的类型是多样而不是单一类型
#其中的应用最熟悉的应该是md5算法(把任意长度的数据映射为128位哈希值)用在cookie中加密用户信息
###论如何实现一个拉链法哈希表
#它也是线性的表,
#所以先创建一个哈希表节点先-先从节点开始然后再hash节点

class Node:
    def __init__(self,item=None):
        self.item=item
        self.next =None



class LinkListNode:
    # 一个节点就是一个链表
    def __init__(self):
        #链表头和尾
        self.head=None
        self.tail=None


    def find(self,data):
        """遍历链表"""
        cur =self.head
        while cur is not None:
            if cur.item == data:
                return True
            else:
                cur=cur.next
        else:
            return False

    def find_items(self):
        """遍历链表"""
        node =self.head
        while node is not None:
            yield node

            #指针下移
            node =node.next

    def append(self,data):
        newNode= Node(data)
        if self.head is None:
            self.head=newNode
            self.tail=newNode
        else:
            self.tail.next=newNode
            self.tail=newNode
    def printData(self):
        list1=[]
        for i in self.find_items():
            list1.append(i.item)
        print( "(("+",".join(map(str,list1))+"))")


#创建哈希表
class HashTable:
    def __init__(self,size=10):
        self.size =size
        self.T =[LinkListNode() for h in range(self.size)]
    def h(self,k):
        return k%self.size
    def find(self,k):
        i=self.h(k)
        return self.T[i].find(k)
    def insert(self,k):
        index =self.h(k)
        if not self.find(index):
            self.T[index].append(k)
        else:
            print("不能重复插入相同的元素")
    def getLength(self):
        return self.size








hash_table =HashTable(30)
for i in range(12):
    hash_table.insert(i)



print(hash_table.find(1))
for h in range(hash_table.getLength()):

    for k in hash_table.T[h].find_items():
        print(h,k.item)
    # hash_table.T[h].printData()




True
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11

基本上满足了去重元素和查找,但是如今哈希表只能处理数字,还是会继续研究达到集合,字典的效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值