直接寻址表

  • 直接寻址表,定义了一个所有关键字的域集合U,根据这个U生成一个包含所有域值的列表T
  • 直接寻址技术优点:
    • 当数据量较小时,相对简单有效
  • 直接寻址技术缺点:
    • 当U很大时,建立列表T,所消耗的内存空间非常大
    • 如果U非常大,而实际出现的key非常少,这样就对空间造成了极大的浪费
    • 当关键字key不是数字的时候就无法处理了

 

hash(哈希)

  • 基本概念:hash,也称作散列、杂凑或者哈希,是一种线性表的存储结构。哈希表由一个直接寻址表和一个哈希函数组成,哈希函数h()将元素的关键字k处理得到唯一的存储元素的位置信息。能把任意长度的输入,通过hash算法转化为固定长度的输出,是一种压缩映射。最大的特点就是从无法从结果推算出输入内容,所以称之为不可逆算法。本质上是通过哈希函数计算数据存储位置的数据结构。
  • hash表示对直接寻址表的改进,具体的
    • 构建大小为m的寻址表T,[0,1,2,3,……,m-1]
    • 将关键字为k的元素,放置在T中的h(k)所指定的位置上
    • h() 是哈希函数,将U中的key映射到寻址表T中
  • 哈希特性:
    • 过程不可逆,即拿到结果也不能反解出输入值是多少
    • 计算速度极快
  • 哈希表存在的问题:
    • 哈希冲突
      • 由于关键字的数量是无限的,而hash创建的寻址表T是有限的,所以必定会出现存储位置冲突或重复,即当h(k)和h(k1)的值相同时,两个值的存储位置是冲突的。
      • 哈希冲突的解决方式:
        • 方式一:开放寻址法,如果哈希函数返回的位置已经有值,则继续向后探寻新的位置来存储这个值。而继续向下探寻位置的方法有
          • 线性探查,如果位置i被占用,则向下探查i+1,i+2 ……直至空位置
          • 二次探查,如果位置i被占用,则依次探查i+1^2,i+2^2……直至空位置
          • 二度哈希:有n个哈希函数,等使用第一个哈希函数h1,发生冲突时,依次尝试使用h2,h3……
        • 方式二:拉链法,哈希表每个位置都链接一个链表,当冲突发生时,冲突的元素被加到该位置链表后面
  • 常见的哈希函数:
    • 除法哈希:  h(k)=k%m
    • 乘法哈希:h(k) = floor(m*(A*key%1))   
    • 全域哈希:h(k) = ((a*key+b) mod p) mod m    a,b =1,2,……p-1
  • hash表的基本操作:
    • insert(key,value) 插入键值对
    • get(key) 根据键取值
    • delete(key)  删除键值对
  • 主要的应用方向:
    • python等语言的字典、集合等数据类型就是基于hash实现的
    • 密码,很多密码都是基于hash构造出来的
    • 可以用于检测文件的一致性
    • 用于数字签名
    • MD5,SHA-1,SHA-2
  • hash表的简单实现(拉链法,单链表)
    • 算法介绍(直接寻址表、hash,MD5,贪心算法、动态规划)
        1 """
        2 使用链表,实现hash。构建一个类似于集合的hash表
        3 """
        4 class LinkList(object):
        5     """
        6     对链表的进一步封装
        7     """
        8     class Node(object):
        9         """
       10         链表的节点类
       11         """
       12         def __init__(self,item):
       13             self.item = item
       14             self.next = None
       15 
       16     class LinkListIterator(object):
       17         """
       18         将链表转为迭代器类
       19         """
       20         def __init__(self,node):
       21             self.node = node
       22 
       23         def __next__(self):
       24             if self.node:
       25                 cur_node = self.node
       26                 self.node = cur_node.next
       27                 return cur_node.item
       28             else:
       29                 raise StopIteration
       30 
       31         def __iter__(self):
       32             return self
       33 
       34     def __init__(self,iterable = None):
       35         self.head = None
       36         self.tail = None
       37         if iterable:
       38             self.extend(iterable)
       39 
       40     def extend(self,iterable):
       41         for obj in iterable:
       42             self.append(obj)
       43 
       44     def append(self,obj):
       45         """
       46         使用尾插法,进行插入
       47         :param obj:
       48         :return:
       49         """
       50         s = LinkList.Node(obj)  # 链表节点创建
       51         if not self.head:
       52             self.head = s
       53             self.tail = s
       54         else:
       55             self.tail.next = s
       56             self.tail = s
       57 
       58     def find(self,obj):
       59         for val in self:
       60             if val == obj:
       61                 return True
       62         else:
       63             return False
       64 
       65     def __iter__(self):
       66         return self.LinkListIterator(self.head)
       67 
       68     def __repr__(self):
       69         return "<<"+",".join(map(str,self)) +">>"
       70 
       71 
       72 class HashTable(object):
       73     """
       74     实现集合的部分功能,不可重复,可查询
       75     """
       76     def __init__(self,size=101):
       77         self.size = size
       78         self.T = [LinkList() for _ in range(self.size)]  # 创建寻址表
       79 
       80     def h_func(self,k):
       81         """
       82         哈希函数
       83         :param k:
       84         :return:
       85         """
       86         return k%self.size
       87 
       88     def find(self,k):
       89         """
       90         根据给定的k值在现有的范围中查找是否存在
       91         :param k:
       92         :return:
       93         """
       94         hash_num = self.h_func(k) # 获取给定数值的hash值
       95         return self.T[hash_num].find(k)
       96 
       97 
       98     def insert(self,k):
       99         """
      100         实现插入前去重
      101         :param k:
      102         :return:
      103         """
      104         if self.find(k):
      105             print('element is exist')
      106         else:
      107             hash_num = self.h_func(k)  # 获取插入的值的hash值
      108             self.T[hash_num].append(k)
      109 
      110 
      111 my_set = HashTable()
      112 my_set.insert(1)
      113 my_set.insert(2)
      114 my_set.insert(102)
      115 print(my_set.T)
      116 print(my_set.find(2))
      View Code

相关文章:

  • 2021-12-10
  • 2021-12-12
  • 2022-02-08
  • 2021-05-08
  • 2022-12-23
  • 2021-08-13
  • 2021-09-23
猜你喜欢
  • 2021-05-27
  • 2021-10-22
  • 2022-12-23
  • 2021-07-26
  • 2021-10-06
相关资源
相似解决方案