Python單向單端鏈表

class Node(object):
    def __init__(self, item):
        self.item = item
        self.next = None

    def __str__(self):
        return str(self.item)


# 單向鏈表
class LinkedList(object):
    def __init__(self):
        self.head: Node = None

    def is_empty(self):
        return self.head is None

    def length(self):
        """
        O(n) 此處可以存儲爲一個長度變量
        :return:
        """
        length = 0
        cur = self.head
        while cur is not None:
            cur = cur.next
            length += 1
        return length

    def append(self, value: object):
        """
        O(n) 將元素添加到最後 如果這裏是雙端鏈表,那麼會有tail指向最後一個,能夠提高到O(1)
        :param value:
        :return:
        """
        node = Node(value)
        cur = self.head
        if cur is None:
            self.head = node
        else:
            while cur.next is not None:  # 只有當前節點有下一個節點, 才進行賦值
                cur = cur.next
            cur.next = node

    def add(self, value: object):
        """
        O(1) 將元素添加到頭部
        :param value:
        :return:
        """
        node = Node(value)
        node.next = self.head  # 將新節點的下一節點指向當前鏈表頭部第一個節點
        self.head = node  # 更新當前鏈表的節點

    def insert(self, index, value):
        """
        O(1) or O(n)
        :param index:
        :param value:
        :return:
        """
        # index = index - 1
        if index <= 0 or self.is_empty():
            self.add(value)  # 在頭部插入
        elif index >= self.length():
            self.append(value)  # 在尾部插入
        else:
            node = Node(value)
            count = 0
            cur = self.head
            while cur is not None:
                if index - 1 == count:  # 判斷是否是需要插入的位置
                    node.next = cur.next  # 將新節點的下一節點指向當前節點(當前cur節點)的下一節點
                    cur.next = node  # 將當前遍歷節點的下一節點指向新節點
                    break
                cur = cur.next
                count += 1

    def insert2(self, index, value):
        """
        O(1) or O(n)
        :param index:
        :param value:
        :return:
        """
        if index <= 0 or self.is_empty():
            self.add(value)  # 在頭部插入
        elif index >= self.length():
            self.append(value)  # 在尾部插入
        else:
            node = Node(value)
            count = 0
            cur = self.head
            while count < (index - 1):
                cur = cur.next
                count += 1
            node.next = cur.next
            cur.next = node

    def reverse(self):
        """
        反轉鏈表: 順序遍歷每個節點, 將每個節點的next指針指向上一個節點
        """
        cur = self.head  # 當前節點指向頭部
        prev_node = None  # 上一個節點

        while cur is not None:
            next_node = cur.next  # 當前節點的下一個節點 必須第一步
            cur.next = prev_node  # 設置當前節點的下一個節點爲上一節點(反轉指向)

            prev_node = cur  # 更新變量 設置上一個節點爲當前節點(下一次循環使用)
            cur = next_node  # 更新變量 設置當前節點爲下一節點(下一次循環使用)

            if cur is not None:  # 最後一個節點的next必定爲None, 所以這裏要判斷 設置head指針指向最後一個節點
                self.head = cur

    def remove(self, item):
        cur = self.head  # 雙指針-當前
        prev_node: Node = None  # 上一個

        while cur is not None:
            if cur.item == item:
                if prev_node is None:  # 上一個節點
                    self.head = cur.next
                else:
                    prev_node.next = cur.next  # 刪除中間元素
                return True
            else:
                prev_node = cur
                cur = cur.next

        return False

    def get(self, index):
        cur = self.head
        count = 0
        while cur is not None:  # 遍歷節點
            if count == index:  # 如果次數一樣
                return cur.item  # 返回元素
            cur = cur.next
            count += 1
        return None

    def find(self, item):
        cur = self.head
        count = 0
        while cur is not None:
            if cur.item == item:
                return count
            cur = cur.next
            count += 1
        return -1

    def __iter__(self):
        """遍歷"""
        cur = self.head
        while cur is not None:
            yield cur.item
            cur = cur.next


if __name__ == '__main__':
    linked = LinkedList()
    assert linked.is_empty() is True

    linked.append(1)
    linked.append(2)
    linked.append(3)
    linked.add(99)

    # 鏈表長度
    li = [i for i in linked]
    assert li == [99, 1, 2, 3]
    assert linked.length() == len(li)

    # 鏈表反轉
    linked.reverse()
    li = [i for i in linked]
    assert li == [3, 2, 1, 99]
    assert linked.length() == len(li)

    # 鏈表插入
    linked.insert(1, 100)
    li = [i for i in linked]
    assert li[1] == 100

    # 鏈表刪除
    linked.remove(100)
    li = [x for x in linked]
    assert li == [3, 2, 1, 99]

    # 獲取元素
    assert linked.get(3) == 99
    assert linked.get(4) is None

    # 查找位置
    assert linked.find(99) == 3
    assert linked.find(3) == 0

    print(li)






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章