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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章