Python 數據結構之單向循環鏈表的實現

單向循環鏈表:

  • 單鏈表的一個變形是單向循環鏈表,鏈表中最後一個節點的next域不再爲None,而是指向鏈表的頭節點。
# 單向循環鏈表基於Python語言的實現
'''
單向循環鏈表需要實現的方法:
is_empty() 鏈表是否爲空
len() 鏈表長度
travel() 遍歷整個鏈表
add(item) 鏈表頭部添加元素
append(item) 鏈表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 刪除節點
search(item) 查找節點是否存在
'''


class Node(object):
    """
    節點類
    """
    def __init__(self, value):
        # 元素域
        self.value = value
        # 鏈接域
        self.next = None


class ReturnOneWayLinkList(object):
    """
    單向鏈表類
    """
    def __init__(self, node=None):
        # 初始化頭節點
        self.__head = node

    def __len__(self):
        """
        返回鏈表長度
        """
        if self.is_empty():
            return 0
        # 遊標,用來遍歷鏈表
        cur = self.__head
        # 記錄遍歷次數
        count = 1
        # 當前節點爲None則說明已經遍歷完畢
        while cur.next != self.__head:
            count += 1
            cur = cur.next
        return count

    def is_empty(self):
        """
        判斷鏈表是否爲空
        """
        # 頭節點不爲None則不爲空
        return self.__head == None

    def add(self, value):
        """
        頭部插入
        要先遍歷得到尾部節點,將尾部節點的next指向這個新節點
        再新節點的next指向頭節點
        再將頭節點替換爲新節點
        順序不可錯,要先保證原鏈表的鏈不斷,否則頭節點後面的鏈會丟失
        """
        node = Node(value)
        # 找到尾部節點,將它的next指向新節點
        cur = self.__head
        while cur.next != self.__head:
            cur = cur.next
        cur.next = node
        # 將新節點的next指向原頭結點
        node.next = self.__head
        # 再將新節點變爲頭結點
        self.__head = node

    def append(self, value):
        """
        尾部插入
        """
        node = Node(value)
        cur = self.__head
        if self.is_empty():
            self.__head = node
            # 將這個節點的next指向head
            node.next = self.__head
        else:
            # 如果不是空先找到尾部節點 遊標從頭節點開始,當遊標的下一個節點等於頭部節點表示找到了尾部節點
            while cur.next != self.__head:
                cur = cur.next
            cur.next = node
            node.next = self.__head

    def insert(self, pos, value):
        """
        指定位置插入元素
        """
        # 應對特殊情況
        if pos <= 0:
            self.add(value)
        elif pos > len(self) - 1:
            self.append(value)
        else:
            node = Node(value)
            prior = self.__head
            count = 0
            # 在插入位置的前一個節點停下
            while count < (pos - 1):
                prior = prior.next
                count += 1
            # 先將插入節點與節點後的節點連接,防止鏈表斷掉,先鏈接後面的,再鏈接前面的
            node.next = prior.next
            prior.next = node

    def remove(self, value):
        """
        移除元素
        """
        if self.is_empty():
            return
        cur = self.__head
        # 設置需要移除節點的上一個節點
        prior = None
        # 設置是否尋找到需要刪除的節點
        is_have = False
        # 尋找尾部節點
        end = self.__head
        while end.next != self.__head:
            end = end.next
        while cur.next != self.__head:
            if value == cur.value:
                is_have = True
                # 判斷此節點是否是頭節點
                if cur == self.__head:
                    self.__head = cur.next
                    # 將尾部節點的next更新爲最新的head
                    end.next = self.__head
                else:
                    prior.next = cur.next
                break
            # 還沒找到節點,繼續遍歷
            else:
                prior = cur
                cur = cur.next
        # 適配尾部移除
        if is_have == False and cur.value == value:
            prior.next = self.__head

    def search(self, value):
        """
        搜索元素
        """
        cur = self.__head
        while cur.next != self.__head:
            if value == cur.value:
                return True
            cur = cur.next
        if cur.value == value:
            return True
        return False

    def travel(self):
        """
        遍歷鏈表
        """
        if self.is_empty():
            return
        cur = self.__head
        while cur.next != self.__head:
            print(cur.value)
            cur = cur.next
        # 適配最後一個元素的遍歷
        print(cur.value)
    

if __name__ == "__main__":
    link_list = ReturnOneWayLinkList()
    link_list.append('a')
    link_list.append('b')
    link_list.add('d')
    # link_list.insert(2, 'c')
    link_list.travel()
    print(len(link_list))
    print(link_list.search('a'))
    print(link_list.search('b'))
    print(link_list.search('c'))
    # # 移除頭部測試
    # link_list.remove('d')
    # # 移除尾部測試
    # link_list.remove('b')
    # 移除中部測試
    link_list.remove('a')
    link_list.travel()
發佈了264 篇原創文章 · 獲贊 202 · 訪問量 110萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章