數據結構在編程世界中一直是很是重要的一環,無論是開發仍是算法,哪怕是單純爲了面試,數據結構都是必修課,今天咱們介紹鏈表中的一種——雙向鏈表的代碼實現。node
好了,話很少說直接上代碼。面試
首先,咱們定義一個節點類:Node算法
class Node: def __init__(self, data): self.data = data self.next = None self.prev = None def getData(self): return self.data def setData(self, data): self.data = data def getNext(self): return self.next def getPrev(self): return self.prev
好,咱們定義了節點類,並實現了獲取、修改節點數據、獲取上一個/下一個節點的方法。編程
經過node = Node(10)
就能夠實例化一個節點啦。數據結構
接下來咱們來定義鏈表類:app
class TwoWayList: def __init__(self): self.head = None self.tail = None self.length = 0
好,咱們定義了一個鏈表類,並設置三個屬性,head表示頭節點,tail表示尾節點,length表示鏈表長度,接下來,咱們給鏈表類添加一些方法。函數
def isEmpty(self): return self.head == None
def append(self, item): if self.length == 0: node = Node(item) self.head = node self.tail = node self.length = 1 return node = Node(item) tail = self.tail tail.next = node node.prev = tail self.tail = node self.length += 1
添加節點的時候,咱們首先要判斷鏈表是否爲空,另外要注意給本來的尾節點設置next屬性,新的尾節點設置prev屬性,更新鏈表的tail和length屬性。測試
def insert(self, index, item): length = self.length if (index<0 and abs(index)>length) or (index>0 and index>=length): return False if index < 0: index = index + length if index == 0: node = Node(item) if self.head != None: self.head.prev = node else: self.tail = node node.next = self.head self.head = node self.length += 1 return True if index == length - 1: return self.append(item) node1 = self.head for i in range(0, index): node1 = node1.next node2 = node1.next node = Node(item) node.prex = node1 node.next = node2 node1.next = node node2.prev = node self.length += 1 return True
插入節點時候,咱們參數爲下標index和數據item,咱們默認在指定下標的後面插入新節點。code
在這裏咱們一樣要特殊考慮頭節點和尾結點的狀況。開發
在執行插入時先將新節點的next、prev屬性指向相應節點,在將先後節點的next和prev指向新節點,同時注意更新鏈表的length屬性。
def get(self, data): node = self.head for i in range(self.length): if node.data == data: return node else: node = node.next else: return False
def getByIndex(self, index): if index >= self.length: return False if index == 0: return self.head now = self.head for i in range(self.length): if i == index: return now now = now.next
def setData(self, index, data): if index >= self.length: return False if index == 0: self.head.data = data now = self.head for i in range(self.length): if i == index: now.data = data return True now = now.next
def remove(self, index): if index >= self.length: return False if index == 0: self.head = self.head.next if self.length != 1: self.head.prev = None self.length -= 1 return True if index == self.length-1: self.tail = self.tail.prev self.tail.next = None self.length -= 1 return True now = self.head for i in range(self.length): if i == index: now.next.prev = now.prev now.prev.next = now.next self.length -= 1 return True now = now.next
注意要更新length屬性,若是刪除頭節點還要更新head屬性,若是刪除尾結點要更新tail屬性。
def reverse(self): now = self.head last = None for i in range(self.length): last = now now = now.next tmp = last.prev last.prev = last.next last.next = tmp tmp = self.head self.head = self.tail self.tail = tmp return True
鏈表翻轉咱們不光要更新tail和head屬性,還要將每個節點上的next和prev屬性調換。
def clear(self): self.head = None self.tail = None self.length = 0
def __str__(self): string = '' node = self.head for i in range(self.length): string += str(node.data) + '/' node = node.next return string
這裏咱們讓print()函數打印鏈表時,從頭節點開始依次打印每一個節點的數據,並用/符號分割。
好啦,一個雙向鏈表咱們就定義好了,並實現了一些操做鏈表的方法,咱們了來測試一下咱們定義的鏈表吧~
li = TwoWayList() li.isEmpty() li.insert(0, 1) li.getByIndex(0) li.remove(0) print(li) li.append(1) print(li) li.append(2) print(li) li.append(4) print(li) li.insert(2,3) print(li) li.insert(3,4) print(li) li.remove(2) print(li) li.setData(2,10) print(li) li.reverse() print(li) print(li.get(2).data) print(li.getByIndex(1).data)
執行上面的操做,檢查一下你的輸出吧,若是你有任何建議歡迎留言告訴我