每個結點有兩個域,左邊部份叫值域,用於存放用戶數據。右邊叫指針域,存儲着指向後面一個節點的指針。
head節點永遠指向第一個節點。
tail節點永遠指向最後一個節點。node
class Node: def __init__(self, item, next=None): self.item = item self.next = next def __str__(self): return '<node: {} -> next: {}>'.format(self.item, self.next.item if self.next else None) def __repr__(self): return str(self.item) class LinkedList: def __init__(self): self.head = None self.tail = None self.size = 0 def append(self, item): node = Node(item) if self.head is None: self.head = node self.tail = node else: self.tail.next = node self.tail = node self.size += 1 return self def index(self, item): for i, node in enumerate(self): if item == node.item: return i else: raise ValueError('item does not exist') def insert(self, index, item): if index < 0: raise IndexError # 若是找到就將current指向對應位置的節點,繼續後面的操做 # 若是沒有找到(鏈表爲空或者索引超界),則追加並當即返回,後面的操做將不會執行 for i, node in enumerate(self): if i == index and node is not self.tail: current = node break else: self.append(item) return node = Node(item) next = current.next # 從頭部插入 if current is self.head: node.next = current self.head = node # 從中間插入(尾部插入即追加,上面已經實現) else: prev = self.head while prev.next is not current: prev = prev.next prev.next = node node.next = current self.size += 1 def pop(self): # 若是頭部或尾部爲空,則表示鏈表爲空 if self.head is None: raise Exception('empty') node = self.tail item = node.item # 若是頭節點沒有後節點,則表示鏈表只有一個元素 if self.head.next is None: self.head = None self.tail = None # 剩下就是有多個節點的狀況 else: prev = self.head while prev.next is not node: prev = prev.next prev.next = None self.tail = prev self.size -= 1 return item def remove(self, index): if index < 0: raise IndexError('does not support negative index') # 若是鏈表爲空,則拋出異常 if self.head is None: raise Exception('empty') # 若是找到就將current指向對應位置的節點,繼續後面的操做 # 若是沒有找到(鏈表爲空或者索引超界),則拋出異常 for i, node in enumerate(self): if i == index: current = node break else: raise IndexError('index out of range') next = current.next # 若是current沒有前節點也沒有後節點,表示只有一個節點 if self.head.next is None: self.head = None self.tail = None # 若是不止一個節點,且current是head elif current is self.head: self.head = next # 若是不止一個節點、current不是head,且current是tail elif current is self.tail: self.pop() # 剩下就是多節點從中間remove的狀況 else: prev = self.head while prev.next is not current: prev = prev.next prev.next = next self.size -= 1 def clear(self): self.head = None self.tail = None self.size = 0 def __iter__(self): current = self.head while current: yield current current = current.next def __len__(self): # current = self.head # count = 0 # while current: # count += 1 # current = current.next # return count return self.size def __getitem__(self, key): for i, node in enumerate(self): if key == i: return node else: raise IndexError('index out of range') def __setitem__(self, key, value): # for i, node in enumerate(self): # if key == i: # node.item = value # else: # self.append(value) self[key].item = value linklist = LinkedList() # 測試append() for i in range(10): linklist.append(i) # 測試__iter__ for node in linklist: print(node) # 測試__len__ print(len(linklist)) # 測試index() print(linklist.index(3)) # print(linklist.index(13)) # 測試__getitem__ print(linklist[3]) # print(linklist[13]) # 測試__setitem__ linklist[5] = 15 print(list(linklist)) # 測試insert() linklist.insert(1, 10) print(list(linklist)) linklist.insert(0, 0) print(list(linklist)) # 測試pop() print(linklist.pop()) # 測試remove() linklist.remove(0) linklist.remove(3) print(list(linklist)) # 測試clear() linklist.clear() print(list(linklist)) print(len(linklist))