data_structure_3_雙鏈表

雙向鏈表

一種更加複雜的鏈表,特徵是每個節點有兩個鏈接:一個指向前一個節點,一個指向後一個節點,處理時只需要管前一個節點的後(next),後一個結節點的前(prev)即可。
特殊情況,當節點爲第一個節點時prev指向空值(None),當節點爲最後一個節點時next指向空值(None)
在這裏插入圖片描述

1.頭部插入更改的代碼以及原理:

		node.next = self.__head
        self.__head = node  
        node.next.prev = node 

在這裏插入圖片描述
2.指定位置插入
指定位置插入有兩種方法:
在這裏插入圖片描述
在這裏插入圖片描述

3.刪除
在這裏插入圖片描述
這裏非常體現操作前一個節點的next,後一個節點的prev。
4.尾部插入(略)

測試代碼

class Node(object):
    """節點"""

    def __init__(self, item):
        self.elem = item
        self.next = None
        self.prev = None  # 多定義一個前驅


class DoubleLinkList(object):
    """雙鏈表"""

    def __init__(self, node=None):  # 3: 如果用戶不輸入頭節點值 當成默認參數 None 直接創建空列表 None 其實又回到了下面一行
        # self.__head = None 1:一上來設置爲空 意思是不指向任何節點 | 私有加 __ 意義:只有這個函數內部使用
        self.__head = node  # 2:在上一行的基礎上人性化,用戶如果先構造節點,就將頭指向這個頭節點 node

    def is_empty(self):
        """鏈表是否爲空"""
        return self.__head is None  # class在變量和None進行比較時,應該使用 is。
        # 可以把比較的值直接作爲返回值 如果相等即爲真就是1 即返回1
        # 只要頭節點指的是空那麼就是空鏈表

    def length(self):
        """鏈表長度"""
        cur = self.__head  # 讓它等於指向表頭指向的第一個節點,cur 用於移動遍歷元素
        # count 記錄數量
        count = 0
        while cur is not None:  # count 從0開始的好處就是能夠記錄空表的長度,一個代碼實現空表與一般表的長度計算
            count += 1
            cur = cur.next  # cur指向了 下一個節點
        return count

    def travel(self):
        """遍歷整個鏈表"""
        cur = self.__head
        while cur is not None:
            print(cur.elem, end=" ")  # 打印每一個元素 空格隔開
            cur = cur.next
        print("")  # 換行

    def add(self, item):
        """鏈表頭部添加元素,頭插法"""
        node = Node(item)  # 把item這個數據封裝成鏈表所需要的節點形式
        node.next = self.__head
        self.__head = node  # 當一開始是空的時候 頭和節點都指向None 所以跑一遍上述兩行還是滿足的
        node.next.prev = node  # node 節點的n指向的p指向node本身

    def append(self, item):
        """鏈表尾部添加元素,尾插法"""
        node = Node(item)
        if self.is_empty():  # 如果鏈表是空的 頭直接指向插入的節點
            self.__head = node
        else:
            cur = self.__head
            while cur.next is not None:
                cur = cur.next
            cur.next = node
            node.prev = cur

    def insert(self, pos, item):
        """指定位置添加元素
            :param item: 元素
            :param pos從0開始
        """
        if pos <= 0:  # 如果輸入位置是<=0的默認是在頭部插入
            ll.add(item)
        elif pos > self.length() - 1:
            self.append(item)
        else:
            cur = self.__head
            count = 0
            while count < pos:  # 不需要兩個遊標只需要一個了
                count += 1
                cur = cur.next
                # 當循環退出後 cur指向pos位置
            node = Node(item)
            node.next = cur  # 這四句話是完成指定位置插入的操作過程
            node.prev = cur.prev
            cur.prev.next = node
            cur.prev = node

    def remove(self, item):
        """刪除節點,找到和你想刪除的數一樣的數"""
        cur = self.__head
        while cur is not None:
            if cur.elem == item:
                # 先判斷此節點是否是頭節點 如果是頭節點
                if cur == self.__head:
                    self.__head = cur.next
                    if cur.next:  # 判斷鏈表是否只有一個元素
                        cur.next.prev = None
                else:
                    cur.prev.next = cur.next
                    if cur.next:
                        cur.next.prev = cur.prev
                break
            else:  # 移動
                cur = cur.next

    def search(self, item):
        """鏈表查找節點是否存在,並返回True或者False"""
        cur = self.__head
        while cur is not None:
            if cur.elem == item:
                return True
            else:
                cur = cur.next
        return False


# 測試代碼
if __name__ == "__main__":
    ll = DoubleLinkList()
    print(ll.is_empty())
    print(ll.length())

    ll.append(1)
    print(ll.is_empty())
    print(ll.length())

    ll.append(2)
    ll.add(8)
    ll.append(3)
    ll.append(4)
    ll.append(5)
    ll.append(6)
    ll.insert(-1, 9)
    ll.travel()
    ll.insert(2, 100)
    ll.travel()
    ll.insert(10, 200)
    ll.travel()
    ll.remove(200)
    ll.travel()
    ll.insert(20, 200)
    ll.travel()
    ll.insert(21, 200)
    ll.travel()
    ll.remove(200)
    ll.travel()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章