zoukankan      html  css  js  c++  java
  • 09-01字典的实现方式

    字典的实现方式

    拉链法

    i = hash(key) % solt
    假设槽位有32个, 那么得到的值很有可能会有冲突, i为最后的该值处于哪个槽位。

    将每个槽位做一个列表, 存值的时候append, 取值的时候遍历。
    如果算法足够好的话, 就几乎能实现近似O(1)了

    实现:
        In [58]: solts = []
            ...: solts_num = 32
            ...: 
            ...: for _ in range(solts_num):
            ...:     solts.append([])
            ...: def put(solts, key, value):
            ...:     i = hash(key) % solts_num
            ...:     solts[i].append((key, value))
            ...: def get(solts, key):
            ...:     i = hash(key) % solts_num
            ...:     for k, v in solts[i]:
            ...:         if k == key:
            ...:             return v
            ...:     raise KeyError(k)
            ...: 
    
        In [59]: put(solts, 'r', 2)
    
        In [60]: solts
        Out[60]: 
        [[],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [('r', 2)],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         []]
    
        In [66]: put(solts, 'd', 2)
    
        In [67]: get(solts, 'd')
        Out[67]: 2
    版本2:实现插入重复key的处理方式
        In [69]: solts = []
            ...: solts_num = 32
            ...: 
            ...: for _ in range(solts_num):
            ...:     solts.append([])
            ...: def put(solts, key, value):
            ...:     i = hash(key) % solts_num
            ...:     p = -1
            ...:     for p, (k, v) in enumerate(solts[i]):
            ...:         if k == key:
            ...:             break
            ...:     else:
            ...:         solts[i].append((key, value))
            ...:         return 
            ...:     if p >=0:
            ...:         solt[i][p] = (key, value)
            ...: def get(solts, key):
            ...:     i = hash(key) % solts_num
            ...:     for k, v in solts[i]:
            ...:         if k == key:
            ...:             return v
            ...:     raise KeyError(k)
            ...: 
    版本3:类的实现
        In [74]: class Dict:
            ...:     def __init__(self, num):
            ...:         self.__solts__ = []
            ...:         self.num = num
            ...:         for _ in range(num):
            ...:             self.__solts__.append([])
            ...:     def put(self, key, value):
            ...:         i = hash(key) % self.num
            ...:         for p, (k, v) in enumerate(self.__solts__[i]):
            ...:             if k == key:
            ...:                 break
            ...:         else:
            ...:             self.__solts__[i].append((key, value))
            ...:             return
            ...:         self.__solts__[i][p] = (key, value)
            ...:     def get(self, key):
            ...:         i = hash(key) % self.num
            ...:         for k, v in self.__solts__[i]:
            ...:             if k == key:
            ...:                 return v
            ...:         raise KeyError(key)
            ...:     
    
        In [75]: d = Dict(32)
    
        In [76]: d.put('r', 2)
    
        In [77]: d.put('d', 2)
    
        In [78]: d.get('r')
        Out[78]: 2
    
    版本4:类的实现, 添加keys方法实现
        In [79]: class Dict:
            ...:     def __init__(self, num):
            ...:         self.__solts__ = []
            ...:         self.num = num
            ...:         for _ in range(num):
            ...:             self.__solts__.append([])
            ...:     def put(self, key, value):
            ...:         i = hash(key) % self.num
            ...:         for p, (k, v) in enumerate(self.__solts__[i]):
            ...:             if k == key:
            ...:                 break
            ...:         else:
            ...:             self.__solts__[i].append((key, value))
            ...:             return
            ...:         self.__solts__[i][p] = (key, value)
            ...:     def get(self, key):
            ...:         i = hash(key) % self.num
            ...:         for k, v in self.__solts__[i]:
            ...:             if k == key:
            ...:                 return v
            ...:         raise KeyError(k)
            ...:     def keys(self):
            ...:         ret = []
            ...:         for solt in self.__solts__:
            ...:             for k, _ in solt:
            ...:                 ret.append(k)
            ...:         return ret
            ...:     
    
        In [80]: d = Dict(32)
    
        In [81]: d.put('r', 2)
    
        In [82]: d.put('d', 2)
    
        In [83]: d.keys()
        Out[83]: ['d', 'r']
    

    开地址法

    i = hash(key) % solt 可以用相同的算法来做
    假设槽位有32个, 那么得到的值很有可能会有冲突, i为最后的该值处于哪个槽位。
    不同的是, 值冲突后的处理方法不同。

    i = fn(key, i) # 如果被占用, 就用算法去找下一个槽。如果槽还是被占用, 就会去找下一个槽。
    取值的时候, 用函数一个一个找下去。

    集合在底层的实现, 就是一个忽略了value的字典

  • 相关阅读:
    Java Web 网络留言板2 JDBC数据源 (连接池技术)
    Java Web 网络留言板3 CommonsDbUtils
    Java Web ConnectionPool (连接池技术)
    Java Web 网络留言板
    Java Web JDBC数据源
    Java Web CommonsUtils (数据库连接方法)
    Servlet 起源
    Hibernate EntityManager
    Hibernate Annotation (Hibernate 注解)
    wpf控件设计时支持(1)
  • 原文地址:https://www.cnblogs.com/cishi/p/13041263.html
Copyright © 2011-2022 走看看