1. 程式人生 > >資料結構(一)單向連結串列的的分析與python程式碼實現

資料結構(一)單向連結串列的的分析與python程式碼實現

概念

       單向連結串列也叫單鏈表,是連結串列中最簡單的一種形式,它的每個節點包含兩個域,一個資訊域(元素域)和一個連結域。這個連結指向連結串列中的下一個節點,而最後一個節點的連結域則指向一個空值。

結構

 程式碼實現




class Node(object):
    """實現單鏈表節點"""
    def __init__(self, item):
        # item存放資料元素
        self.item = item
        # next代表下一個節點
        self.next = None


class SingleLinkList(object):
    """單鏈表"""
    def __init__(self):
        self.head = None

    # 連結串列是否為空
    def is_empty(self):
        return self.head is None

    # 連結串列長度
    def length(self):

        # cur初始時指向頭節點
        cur = self.head
        n = 0
        # 當未到達尾節點None時
        while cur is not None:
            n += 1
            # 將cur後移一個節點
            cur =cur.next

        return n

    # 遍歷整個連結串列
    def travel(self):
        cur = self.head
        while cur is not None:
            print(cur.item, end='-')
            cur = cur.next
        # 輸出連結串列
        print()


    # 連結串列頭部新增元素
    def add(self, item):
        # 呼叫Node類,例項node物件
        node = Node(item)

        # 先讓新增加的節點next指向原首節點
        node.next = self.head
        # 然後讓head指向新節點
        self.head = node


    # 連結串列尾部新增元素
    def append(self, item):

        # 若連結串列為空,則直接在頭部新增
        if self.is_empty():
            self.add(item)
            return
        # 1、連結串列不為空,需要遍歷查詢尾節點
        cur = self.head
        while cur.next is not None:
            cur = cur.next

        # 至此cur指向當前連結串列的尾節點
        # 2、讓cur的next指向新節點
        node = Node(item)
        cur.next = node

    # 指定位置新增元素
    def insert(self, pos, item):
        # 需要對新增的位置進行分類討論
        # 如果新增位置<=0,則直接在頭部新增
        if pos <= 0:
            self.add(item)
        # 位置大於連結串列長度,則直接新增到尾部
        elif pos >= self.length():
            self.append(item)
        else:
            # 1 遍歷查詢待插入位置的前一個節點cur
            cur = self.head
            for i in range(pos-1):
                cur = cur.next
            # 至此,cur指向的就是待插入位置的前一個節點
            # 2 新節點的next指向cur的next
            node = Node(item)
            node.next = cur.next
            # 3 cur的next指向新節點
            cur.next = node

    # 刪除節點
    def remove(self, item):
        # 思路:讓待刪節點的pre(前節點)next指向待刪節點的next
        cur = self.head
        pre = None
        # 1 找到待刪節點並記錄前一個節點
        while cur is not None:
            # 待刪節點不存在也就不用刪了,若存在
            if cur.item == item:
                # 2 若有前一個節點,pre的next指向cur的next
                if pre is not None:
                    pre.next = cur.next
                # 否則(待刪節點是第0個節點),head指向cur的next
                else:
                    self.head = cur.next

                return
            pre = cur
            cur = cur.next

    # 查詢某個節點是否存在
    def search(self, item):
        cur = self.head
        while cur is not None:
            if cur.item == item:
                return True
            cur = cur.next

        # 沒有找到
        return False


# 測試程式碼
if __name__ == '__main__':
    sl = SingleLinkList()
    sl.add(1)
    sl.add(2)
    sl.add(3)
    sl.travel()
    # 結果3-2-1-
    sl.append("abc")
    sl.append("def")
    sl.append("ghi")
    sl.travel()
    # 結果3-2-1-abc-def-ghi-
    sl.insert(-1, "xx")
    sl.insert(99, "yy")
    sl.insert(3, "zz")
    sl.travel()
    # 結果xx-3-2-zz-1-abc-def-ghi-yy-
    sl.remove("xx")
    sl.remove("yy")
    sl.remove(1)
    sl.remove(90)
    sl.travel()
    # 結果3-2-zz-abc-def-ghi-
    print(sl.search(3))
    # 結果True
    print(sl.search("zz"))
    # 結果True
    print(sl.search(380))
    # 結果False

複雜度

操作 連結串列 順序表
訪問元素 O(n) O(1)
在頭部插入/刪除 O(1) O(n)
在尾部插入/刪除 O(n) O(1)
在中間插入/刪除 O(n) O(n)