鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,可是並不會按線性的順序存儲數據,而是在每個節點裏存到下一個節點的指針(Pointer)。—— 維基百科html
鏈表的基本構造塊是節點(Node)。咱們將在文章的第2部分經過Python實現一個簡單的Node類。前端
一個單向鏈表的構造以下圖1所示包含兩個域:python
注1:必須明確指定鏈表的第一項的位置。一旦咱們知道第一項在哪裏,第一項目能夠告訴咱們第二項是什麼,依次類推。按照一個方向遍歷,直到最後一項(最後一個節點),最後一項須要知道沒有下一項。
注2:這些節點在邏輯上是相連的,但要知道它們在物理內存上並不相連。git
咱們先來實現Node類:github
class Node(object): def __init__(self, initdata): self.data = initdata # 引用None表明沒有下一節點 self.next = None # 得到數據 def getData(self): return self.data # 得到下一個節點的引用 def getNext(self): return self.next # 修改數據 def setData(self, newdata): self.data = newdata # 修改下一節點的引用 def setNext(self, newnext): self.next = newnext
建立一個Node對象試試:數據結構
>>> tmp = Node(33) >>> tmp <__main__.Node object at 0x1022699b0> >>> tmp.getData() 33
只要知道第一個節點(包含第一個項),那麼以後的每一個節點均可以經過指向下一個節點的連接 依次找到。
考慮到這樣的狀況,Unordered List類只要維護對第一個節點的引用就能夠了。Unordered List類自己不包含任何節點對象,它只包含對鏈表結構中第一個節點的單個引用!測試
class unOrderedList(): def __init__(self): # 初始化None表示此時鏈表的頭部不引用任何內容 self.head = None
建立一個空的鏈表試試(如圖2所示):spa
>>> myList = unOrderedList()
咱們可經過下面的 isEmpty()
方法檢查是否爲空鏈表:指針
# 只有在鏈表中沒有節點的時候爲真 def isEmpty(self): return self.head == None
添加元素後的鏈表是這樣的(如圖3所示),稍後在文章第3部分實現添加方法:code
add()
在鏈表前端添加元素因爲是在前端添加,所以最後添加的在最前端。
def add(self, item): temp = Node(item) # Step0:建立一個新節點並將新項做爲數據 temp.setNext(self.head) # Step1:更改新節點的下一個引用以引用舊鏈表的第一個節點 self.head = temp # Step2:從新設置鏈表的頭以引用新節點
添加元素——執行mylist.add(26)
時候的圖解以下:
>>> mylist.add(31) >>> mylist.add(77) >>> mylist.add(17) >>> mylist.add(93) >>> mylist.add(26)
size()
求鏈表長度def size(self): current = self.head count = 0 while current != None: count += 1 current = current.getNext() return count
經過current
遍歷鏈表並對節點計數。
圖解以下:
search()
查找def search(self, item): current = self.head found = False while current != None and not found: if current.getData() == item: found = True else: current = current.getNext() return found
經過current
遍歷鏈表,使用found
標記是否找到了正在尋找的項。
圖解以下:
remove()
刪除def remove(self, item): current = self.head previous = None found = False while not found: if current.getData() == item: found = True else: previous = current current = current.getNext() if previous == None: # 當要刪除的項目剛好是鏈表中的第一個項,這時候prev是None,須要修改head以引用current以後的節點 self.head = current.getNext() else: previous.setNext(current.getNext())
咱們遍歷鏈表,先搜索,再刪除。
1.搜索:
使用previous
與current
進行移動,藉助found
標記是否找到。
一旦found
爲True,current
就是對包含要刪除的項的節點的引用。
2.刪除(修改引用):
咱們把previous
的對下一節點的引用設爲current
的下一節點。
以上兩過程的圖解以下:
參考:
problem-solving-with-algorithms-and-data-structure-using-python
python-wikipedia
若有錯誤,還望指正~
完整實現及測試可在Github找到:Python-DataStructure-Implementation感謝。