数据结构--链表法解决冲突问题构造的哈希表/LRU缓存淘汰算法

1. 链表法解决冲突问题构造的哈希表

1.1 哈希表:

线性表和树等线性结构中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需要进行一系列和关键字的比较。理想的情况是希望不经过任何比较,一次存取便能够取到所查找的记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字和结构中一个唯一的存储位置相对应。因而在查找时,只要根据这个对应关系f找到给定值K的像f(k)。若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上,因此,不需要进行比较便可以直接取得所查记录。在此,我们称这个对应关系f为哈希函数,按照这个思想建立的表为哈希表。
  哈希函数的构造方法很多,常用的有直接定址法、数字分析法、平方取中法、折叠法、除留余数法、随机数法等

1.2 冲突问题:

对于不同的关键字可能得到同一哈希地址,即 key1!=key2,而f(key)=f(key2),这种现象叫做冲突,在一般情况下,冲突只能尽可能的少,而不能完全避免。因为,哈希函数是从关键字集合到地址集合的映像。通常,关键字集合比较大,它的元素包括多有可能的关键字,而地址集合的元素因为哈希表中的地址值。既然如此,那么,如何处理冲突则是构造哈希表不可缺少的。
  通常用于处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

1.3 解决方法:链地址法

  • (1)采用除留余数法构造哈希函数,冲突解决采用链地址法。
  • (2)具体的关键字列表为(19,14,23,01,68,20,84,27,55,11,10,79),则哈希函数为H(key)=key MOD 13。则采用除留余数法和链地址法后得到的预想结果应该为:
      在这里插入图片描述
  • 哈希造表完成后,进行查找时,首先是根据哈希函数找到关键字的位置链,然后在该链中进行搜索,如果存在和关键字值相同的值,则查找成功,否则若到链表尾部仍未找到,则该关键字不存在。
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 16 21:06:20 2019

@author: janti
"""
class Node:
    def __init__(self,key,value):
        self.key=key
        self.value=value
        self.next=None
        

class ChainHash:
    def __init__(self,capacity):
         self.capacity=capacity
         self.table=[None]*capacity
    def buildHash(self,lista):
        for i in range(len(lista)):
            value=int(lista[i])
            key=value % 13
            print(key)
            node_=self.table[key]
        
            if node_ is None:
                self.table[key]=Node(key,value)
            else:
                while node_.next is not None:
                    if node_.key == key:
                        node_.value = value
                        return
                    node_ = node_.next
                node_.next = Node(key, value)
        
    
        
    def InsertHash(self,value):
        key=value % 13
        node_=self.table[key]
        if node_ is None:
            self.table[key]=Node(key,value)
        else:
            while node_.next is not None:
                if node_.key == key:
                    node_.value = value
                    return
                node_ = node_.next
            node_.next = Node(key, value)
            
    def SearchHash(self,key,value):
        node_ = self.table[key]
        while node_ is not None:
            if node_.value == value:
                return node_ # 返回该指针位置
            node_ = node_.next
        return None    # 若没有找到该数值,则返回空
# In[]
if __name__ == '__main__':
    s=ChainHash(20)
    lista=[1,6,11,14,19]
    
    # In[]
    s.buildHash(lista)
        # In[]
    s.InsertHash(27)
#    print(s.table)
     # In[]
    print(s.SearchHash(1,17))
        

参考链接:

https://www.cnblogs.com/lpshou/archive/2012/05/08/2490191.html

2. LRU缓存淘汰算法

2.1 原理

LRU(Least recently used,最近最少使用)缓存算法根据数据最近被访问的情况来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

在这里插入图片描述
下图中,介绍了一个缓存空间为5的缓存队列,当访问数据的顺序是:1,2,3,4,5,6,7,6,4,0 时空间中数据的变化过程。

在这里插入图片描述

  1. 当缓存空间未满时,数据一直往新的空间写;
  2. 当缓存满,并且缓存中没有需要访问的数据时,最先进入缓存的数据被淘汰掉;
  3. 当缓存满,并且缓存中有需要访问的数据时,做了一个数据交换,把访问的数据拿出来,其余数据往下压,最后把访问的数据放到顶部

2.2 代码原理

参考链接:

https://blog.csdn.net/qq1332479771/article/details/69370779
https://zhuanlan.zhihu.com/p/34989978

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值