概念介紹
上一博文已經介紹了Python實現單向無序鏈表的實現方式,這篇博文來介紹Python如何實現單向有序鏈表。有序和無序僅僅指節點所包含的數據成員的大小排列順序,有序指各個節點按照節點數據成員的大小順序排序,從大到小或從小到大。無序則可以任意排列。
鏈表節點實現
實現方式完全同單向無序列表,這里不再過多介紹,感興趣的可以看Python實現單向無序鏈表(Singly linked list)關於節點的實現方式。
鏈表實現
鏈表的實現中,鏈表初始化,判斷是否為空,獲取鏈表長度與無序鏈表一致。同時,remove方式的實現也相同,都是遍歷鏈表,找到指定節點,然后刪除。主要的區別在於查找和添加(search和add方法)有所區別。
在無序鏈表中,查找是依次遍歷各個節點,直至找到該節點,若節點不存在於鏈表中,也會一直遍歷直到鏈表尾部。對於有序鏈表來說,由於各個節點的數據成員是有大小排序的,則查找算法可以有所優化。假如有這樣一個有序鏈表,鏈表中各個節點的數據依次為17,26,31, 54,77,93。是按從小到大的順序依次排序。如果我們想查找節點數據成員為45的節點是否在鏈表中,當我們找到31所在的節點時,其下一個節點數據類型為54,而45正好在31和54之間,卻沒有在鏈表中找到,則45所在的節點不存在,且不需要再繼續遍歷鏈表,因為隨后的節點數據成員都比54要大。如下圖所示。
下面來實現其算法,依然是遍歷各個節點,若找到則返回True,若當前節點的數據成員值>item,則為找到,不需要繼續遍歷后續節點,因為后續節點的值比當前節點的值還要大。
若當前節點的值<item,則繼續遍歷。若鏈表為空或找到鏈表尾部依然沒找到,則直接返回False。
def search(self, item):
current = self.head
while current is not None:
if current.get_data() == item:
return True
if current.get_data() > item:
return False
else:
current = current.get_next()
return False
接下來實現有序鏈表的add(添加新節點)方法。注意,在無序列表中,新添加的節點成為了鏈首節點,這種實現方式很簡單。但在有序鏈表中,添加方法必須在插入鏈表后,依然要保持整個鏈表的有序狀態(從大到小或從小到大)。假如有這樣一個鏈表,節點的大小順序為17,26,54, 77,93,我們想將31添加到鏈表中,顯然應該添加到26和54中間的位置。
下面介紹實現原理:首先要插入節點,必然有一個當前節點和上一個節點,分別用current和previous指代。最后的目的是將指定節點插入到當前節點和上一個節點中間。
首先遍歷節點,若當前節點的值大於指定節點的值,而顯然后續的節點值比當前節點的值更大,則鏈表終止遍歷。指定節點的值顯然在當前節點和上一節點之間。若當前節點的值比指定節點的值小,則繼續遍歷,直至到最后一個節點。最后判斷若上一個節點為空,則當前節點為空或當前節點的值比指定節點的值大,直接將當前節點設置為指定節點,插入到鏈首。若上一個節點不為空,直接將指定節點插入到二者之間(當前節點和上一個節點)。
def add(self, item):
current = self.head
previous = None
while current is not None:
if current.get_data() > item:
break
previous = current
current = current.get_next()
temp = Node(item)
if previous is None:
temp.set_next(self.head)
self.head = temp
else:
temp.set_next(current)
previous.set_next(temp)
其他方法也可以按照類似的方式實現,其中pop方法同無序鏈表。