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的字典

posted @ 2020-06-04 07:14  此时  阅读(164)  评论(0编辑  收藏  举报