2019年12月19日 很久沒寫博客了,開一個有關源代碼解析的,希望有朝一日能夠寫出些東西
目錄
OrderedDict源代碼分析
實現思路
實際上想了解這個OrderedDict源代碼實現的原因是leetcode-LRU緩存實現這道題裏的題解使用到了這個模塊
實現OrderedDict模塊的思路與實現LRU緩存的思路相似,都是利用哈希表實現在O(1)時間內查找目標以及利用雙向鏈表實現對元素輸入順序的記錄。但不同的是OrderedDict的鏈表爲雙向循環列表,用來實現逆序輸出。
源代碼
class OrderedDict(dict):
def __init__(self, *args, **kwds):
if not args:
raise TypeError("descriptor '__init__' of 'OrderedDict' object "
"needs an argument")
self = args[0]
args = args[1:]
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__root
except AttributeError:
# 此處構建了哨兵節點
self.__root = root = []
# 構建雙端循環鏈表
root[:] = [root, root, None]
self.__map = {}
self.__update(*args, **kwds)
def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
'od.__setitem__(i, y) <==> od[i]=y'
if key not in self:
root = self.__root
last = root[0]
last[1] = root[0] = self.__map[key] = [last, root, key]
return dict_setitem(self, key, value)
def __delitem__(self, key, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
dict_delitem(self, key)
link_prev, link_next, _ = self.__map.pop(key)
link_prev[1] = link_next # update link_prev[NEXT]
link_next[0] = link_prev # update link_next[PREV]
def __iter__(self):
'od.__iter__() <==> iter(od)'
root = self.__root
curr = root[1] # start at the first node
while curr is not root:
yield curr[2] # yield the curr[KEY]
curr = curr[1] # move to next node
def __reversed__(self):
'od.__reversed__() <==> reversed(od)'
root = self.__root
curr = root[0] # start at the last node
while curr is not root:
yield curr[2] # yield the curr[KEY]
curr = curr[0] # move to previous node
def clear(self):
'od.clear() -> None. Remove all items from od.'
root = self.__root
root[:] = [root, root, None]
self.__map.clear()
dict.clear(self)
源代碼解析
OrderedDict的實現以dict作爲基類,許多方法由dict中繼承。在該類的實現中,雙端鏈表的實現爲self.__root=root=[],root[:]=[root,root,None],其中那個self.__root表示雙端鏈表的哨兵節點,在每一個類初始化時都會被生成,該節點的表示含義如下node=[prev,next,key],哨兵節點沒有key。每一個節點都利用李哥list實現,list中的元素爲可變元素,也即其他的節點(list)。self.__map利用字典實現key與節點的映射。__setitem__實現向列表中插入節點,同時在map中實現key與節點的映射。每次插入節點時都是在哨兵節點的前方插入節點,因此哨兵節點總是鏈表的最後一個節點(順序)或者第一個節點(逆序)。__delitem__利用map查詢到相應的節點,修改相應節點的前後節點實現節點的刪除。
python list.sort 的實現
實現思路——timesort
timesort的實現原理是基於待排序的數組中可能存在由有序部分的情況,最數組進行劃分,分出有序的部分,然後對這些部分進行插入排序或二分插入排序等操作實現數組的有序化,對於較短的數組實行插入排序,否則就是timesort,具體的原理如下:
源代碼
python的源代碼是基於C++實現的,代碼如:python timesort代碼
基於python的實現:python 實現