用 python 學習資料結構(二)雙向連結串列
阿新 • • 發佈:2018-12-15
##一、相比單向連結串列,雙向連結串列的優勢 雙向連結串列的每個節點儲存了前一個節點和後一個節點的引用(指標),到達某個節點是,可以向前或者向後遍歷,提高了操作的效率。比如,insertBefore(nodeA, value) 操作,可以一步完成,而不需要先查詢 nodeA 的前序節點。
newNode = ListNode(value)
nodeA.prev.next = newNode
newNode.prev = nodeA.prev
newNode.next = nodeA
nodeA.prev = newNode
##二、關於List 的遍歷訪問,使用迭代器。 可以把迭代器理解為指向 List 的一個遊標,這個遊標可以向前或者向後(一般是從前向後遍歷)遍歷整個 List。 如果我們的 List 想要支援迭代訪問,比如 for val in listA: xxx, 就必須實現迭代器,必須要實現自己的迭代器類和迭代方法。
##三、語言描述總數太抽象,直接看程式碼吧。 如果發現問題或者有疑問,歡迎與我討論。看完程式碼,相信你對 python 的迭代器以及可迭代物件有了新的認識。
歡迎加入我們免費的 python 學習交流社群,請先掃描群主二維碼,加群主為好友,然後申請入群。群內技術大牛每日交流,即時答疑。也歡迎關注我們的技術公眾號,會定期推送學習材料(簡書markdown 圖片尺寸好像不能調整,醜哭)。
# -*- coding: utf-8 -*- # 定義節點類,儲存資料和前後物件的引用 class ListNode(): def __init__(self,value): self.value = value self.next = None self.prev = None # 根據 python 的迭代器規範,定義一個迭代器 class ListIterator(): def __init__(self, l): self.list = l self.cur = l.head def __iter__(self): return self # next 函式,用來返回下一個資料 def next(self): if self.cur.next == l.tail: # 如果迭代結束了,按照規範需要丟擲 StopIteration 異常 raise StopIteration() else: self.cur = self.cur.next return self.cur.value # 定義List類,實現可迭代操作的介面 class List(): def __init__(self): self.head = ListNode(0) self.tail = ListNode(0) self.head.next = self.tail self.tail.prev = self.head self.count = 0 def __len__(self): return self.count def __iter__(self): return ListIterator(self) # 插入列表尾部 def append(self, value): return self.insertBefore(self.tail, value) # 插入列表頭部 def addFirst(self, value): return self.insertAfter(self.head, value) def find(self, value): cur = self.head.next while cur and cur.value != value: cur = cur.next return cur # 刪除一個節點 def remove(self, node): node.prev.next = node.next node.next.prev = node.prev self.count -= 1 # 在某個節點前面插入新的資料 def insertBefore(self, node, value): newNode = ListNode(value) node.prev.next = newNode newNode.prev = node.prev newNode.next = node node.prev = newNode self.count+=1 return newNode # 有沒有發現雙向連結串列的插入操作實現起來非常的簡單了 def insertAfter(self, node, value): return self.insertBefore(node.next, value) if __name__ == '__main__': # append l = List() l.append(1) l.append(2) l.append(3) # find v1 = l.find(1) v2 = l.find(2) v3 = l.find(3) print(v1.value) print(v2.value) #remove l.remove(v1) l.remove(v2) #insert before v22 = l.insertBefore(v3, -2) v33 = l.insertBefore(v22, -3) #insert after v4 = l.insertAfter(v3, 4) v5 = l.insertAfter(v4, 5) #count 5 print(len(l)) #print list -3, -2, 3, 4, 5 for val in l: print val,