Python實現單向有序鏈表(Singly linked list)


概念介紹

上一博文已經介紹了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方法同無序鏈表。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM