日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

數據結構——鏈表(python版)

作者:別出BUG求求了 更新時間: 2023-11-13 編程語言

一、鏈表簡介

鏈表是一種在存儲單元上非連續、非順序的存儲結構。數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現。鏈表是由一系列的結點組成,結點可以在運行時動態生成。每個結點包含兩部分:數據域與指針域。數據域存儲數據元素,指針域存儲下一結點的指針。

二、單向鏈表

單向鏈表也叫單鏈表,是鏈表中最簡單的形式,它的每個節點包含兩個域,一個信息域(元素域)和一個鏈接域。這個鏈接指向鏈表中的下一個節點,而最后一個節點的鏈接域則指向一個空值。
在這里插入圖片描述
head 保存首地址,item 存儲數據,next 指向下一結點地址。

鏈表失去了序列的隨機讀取優點,同時鏈表增加了指針域,空間開銷也較大,但它對存儲空間的使用要相對靈活。

列如:有一堆數據[1,2,3,5,6,7],要在3和5之間插入4, 如果用數組,需要將5之后的數據都往后退一位,然后再插入4,這樣非常麻煩,但是如果用鏈表,我就直接在3和5之間插入4就行。

1. 定義結點

結點的數據結構為數據元素(item)與 指針(next)

class Node(object):
    """單鏈表的結點"""

    def __init__(self, item):
        # item存放數據元素
        self.item = item
        # next是下一個節點的標識
        self.next = None

2. 定義鏈表

鏈表需要具有首地址指針head。

class SingleLinkList(object):
    """單鏈表"""

    def __init__(self):
        self._head = None

示例:創建鏈表

if __name__ == '__main__':
    # 創建鏈表
    link_list = SingleLinkList()
    # 創建結點
    node1 = Node(1)
    node2 = Node(2)

    # 將結點添加到鏈表
    link_list._head = node1
    # 將第一個結點的next指針指向下一結點
    node1.next = node2

    # 訪問鏈表
    print(link_list._head.item)  # 訪問第一個結點數據
    print(link_list._head.next.item)  # 訪問第二個結點數據

是不是感覺很麻煩,所以我們要在鏈表中增加操作方法。

  • is_empty() 鏈表是否為空
  • length() 鏈表長度
  • items() 獲取鏈表數據迭代器
  • add(item) 鏈表頭部添加元素
  • append(item) 鏈表尾部添加元素
  • insert(pos, item) 指定位置添加元素
  • remove(item) 刪除節點
  • find(item) 查找節點是否存在

代碼如下:

class SingleLinkList(object):
    """單鏈表"""

    def __init__(self):
        self._head = None

    def is_empty(self):
        """判斷鏈表是否為空"""
        return self._head is None

    def length(self):
        """鏈表長度"""
        # 初始指針指向head
        cur = self._head
        count = 0
        # 指針指向None 表示到達尾部
        while cur is not None:
            count += 1
            # 指針下移
            cur = cur.next
        return count

    def items(self):
        """遍歷鏈表"""
        # 獲取head指針
        cur = self._head
        # 循環遍歷
        while cur is not None:
            # 返回生成器
            yield cur.item
            # 指針下移
            cur = cur.next

    def add(self, item):
        """向鏈表頭部添加元素"""
        node = Node(item)
        # 新結點指針指向原頭部結點
        node.next = self._head
        # 頭部結點指針修改為新結點
        self._head = node

    def append(self, item):
        """尾部添加元素"""
        node = Node(item)
        # 先判斷是否為空鏈表
        if self.is_empty():
            # 空鏈表,_head 指向新結點
            self._head = node
        else:
            # 不是空鏈表,則找到尾部,將尾部next結點指向新結點
            cur = self._head
            while cur.next is not None:
                cur = cur.next
            cur.next = node

    def insert(self, index, item):
        """指定位置插入元素"""
        # 指定位置在第一個元素之前,在頭部插入
        if index <= 0:
            self.add(item)
        # 指定位置超過尾部,在尾部插入
        elif index > (self.length() - 1):
            self.append(item)
        else:
            # 創建元素結點
            node = Node(item)
            cur = self._head
            # 循環到需要插入的位置
            for i in range(index - 1):
                cur = cur.next
            node.next = cur.next
            cur.next = node

    def remove(self, item):
        """刪除節點"""
        cur = self._head
        pre = None
        while cur is not None:
            # 找到指定元素
            if cur.item == item:
                # 如果第一個就是刪除的節點
                if not pre:
                    # 將頭指針指向頭節點的后一個節點
                    self._head = cur.next
                else:
                    # 將刪除位置前一個節點的next指向刪除位置的后一個節點
                    pre.next = cur.next
                return True
            else:
                # 繼續按鏈表后移節點
                pre = cur
                cur = cur.next

    def find(self, item):
        """查找元素是否存在"""
        return item in self.items()

示例:操作鏈表

if __name__ == '__main__':
    link_list = SingleLinkList()
    # 向鏈表尾部添加數據
    for i in range(5):
        link_list.append(i)
    # 向頭部添加數據
    link_list.add(6)
    # 遍歷鏈表數據
    for i in link_list.items():
        print(i, end='\t')
    # 鏈表數據插入數據
    link_list.insert(3, 9)
    print('\n', list(link_list.items()))
    # 刪除鏈表數據
    link_list.remove(0)
    # 查找鏈表數據
    print(link_list.find(4))

三、循環鏈表

在這里插入圖片描述
單向循環鏈表為單向鏈表的變種,鏈表的最后一個next指向鏈表頭,新增一個循環。

1. 循環鏈表結點

class Node(object):
    """鏈表的結點"""

    def __init__(self, item):
        # item存放數據元素
        self.item = item
        # next是下一個節點的標識
        self.next = None

2. 定義循環鏈表

class SingleCycleLinkList(object):

    def __init__(self):
        self._head = None

    def is_empty(self):
        """判斷鏈表是否為空"""
        return self._head is None

    def length(self):
        """鏈表長度"""
        # 鏈表為空
        if self.is_empty():
            return 0
        # 鏈表不為空
        count = 1
        cur = self._head
        while cur.next != self._head:
            count += 1
            # 指針下移
            cur = cur.next
        return count

    def items(self):
        """ 遍歷鏈表 """
        # 鏈表為空
        if self.is_empty():
            return
        # 鏈表不為空
        cur = self._head
        while cur.next != self._head:
            yield cur.item
            cur = cur.next
        yield cur.item

    def add(self, item):
        """ 頭部添加結點"""
        node = Node(item)
        if self.is_empty():  # 為空
            self._head = node
            node.next = self._head
        else:
            # 添加結點指向head
            node.next = self._head
            cur = self._head
            # 移動結點,將末尾的結點指向node
            while cur.next != self._head:
                cur = cur.next
            cur.next = node
        # 修改 head 指向新結點
        self._head = node

    def append(self, item):
        """尾部添加結點"""
        node = Node(item)
        if self.is_empty():  # 為空
            self._head = node
            node.next = self._head
        else:
            # 尋找尾部
            cur = self._head
            while cur.next != self._head:
                cur = cur.next
            # 尾部指針指向新結點
            cur.next = node
            # 新結點指針指向head
            node.next = self._head

    def insert(self, index, item):
        """ 指定位置添加結點"""
        if index <= 0:  # 指定位置小于等于0,頭部添加
            self.add(item)
        # 指定位置大于鏈表長度,尾部添加
        elif index > self.length() - 1:
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            # 移動到添加結點位置
            for i in range(index - 1):
                cur = cur.next
            # 新結點指針指向舊結點
            node.next = cur.next
            # 舊結點指針 指向 新結點
            cur.next = node

    def remove(self, item):
        """ 刪除一個結點 """
        if self.is_empty():
            return
        cur = self._head
        pre = Node
        # 第一個元素為需要刪除的元素
        if cur.item == item:
            # 鏈表不止一個元素
            if cur.next != self._head:
                while cur.next != self._head:
                    cur = cur.next
                # 尾結點指向 頭部結點的下一結點
                cur.next = self._head.next
                # 調整頭部結點
                self._head = self._head.next
            else:
                # 只有一個元素
                self._head = None
        else:
            # 不是第一個元素
            pre = self._head
            while cur.next != self._head:
                if cur.item == item:
                    # 刪除
                    pre.next = cur.next
                    return True
                else:

                    pre = cur  # 記錄前一個指針
                    cur = cur.next  # 調整指針位置
        # 當刪除元素在末尾
        if cur.item == item:
            pre.next = self._head
            return True

    def find(self, item):
        """ 查找元素是否存在"""
        return item in self.items()


if __name__ == '__main__':
    link_list = SingleCycleLinkList()
    print(link_list.is_empty())
    # 頭部添加元素
    for i in range(5):
        link_list.add(i)
    print(list(link_list.items()))
    # 尾部添加元素
    for i in range(6):
        link_list.append(i)
    print(list(link_list.items()))
    # 添加元素
    link_list.insert(3, 45)
    print(list(link_list.items()))
    # 刪除元素
    link_list.remove(5)
    print(list(link_list.items()))
    # 元素是否存在
    print(4 in link_list.items())

四、雙向鏈表

雙向鏈表比單向鏈表更加復雜,它每個節點有兩個鏈接:一個指向前一個節點,當此節點為第一個節點時,指向空值;而另一個鏈接指向下一個節點,當此節點為最后一個節點時,指向空值。

在這里插入圖片描述

head 保存首地址,item 存儲數據,next 指向下一結點地址,prev 指向上一結點地址。

1. 定義雙向鏈表結點

class Node(object):
    """雙向鏈表的結點"""

    def __init__(self, item):
        # item存放數據元素
        self.item = item
        # next 指向下一個節點的標識
        self.next = None
        # prev 指向上一結點
        self.prev = None

2. 定義雙向鏈表

class BilateralLinkList(object):
    """雙向鏈表"""

    def __init__(self):
        self._head = None

    def is_empty(self):
        """判斷鏈表是否為空"""
        return self._head is None

    def length(self):
        """鏈表長度"""
        # 初始指針指向head
        cur = self._head
        count = 0
        # 指針指向None 表示到達尾部
        while cur is not None:
            count += 1
            # 指針下移
            cur = cur.next
        return count

    def items(self):
        """遍歷鏈表"""
        # 獲取head指針
        cur = self._head
        # 循環遍歷
        while cur is not None:
            # 返回生成器
            yield cur.item
            # 指針下移
            cur = cur.next

    def add(self, item):
        """向鏈表頭部添加元素"""
        node = Node(item)
        if self.is_empty():
            # 頭部結點指針修改為新結點
            self._head = node
        else:
            # 新結點指針指向原頭部結點
            node.next = self._head
            # 原頭部 prev 指向 新結點
            self._head.prev = node
            # head 指向新結點
            self._head = 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
            # 新結點上一級指針指向舊尾部
            node.prev = cur
            # 舊尾部指向新結點
            cur.next = node

    def insert(self, index, item):
        """ 指定位置插入元素"""
        if index <= 0:
            self.add(item)
        elif index > self.length() - 1:
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            for i in range(index):
                cur = cur.next
            # 新結點的向下指針指向當前結點
            node.next = cur
            # 新結點的向上指針指向當前結點的上一結點
            node.prev = cur.prev
            # 當前上一結點的向下指針指向node
            cur.prev.next = node
            # 當前結點的向上指針指向新結點
            cur.prev = node

    def remove(self, item):
        """ 刪除結點 """
        if self.is_empty():
            return
        cur = self._head
        # 刪除元素在第一個結點
        if cur.item == item:
            # 只有一個元素
            if cur.next is None:
                self._head = None
                return True
            else:
                # head 指向下一結點
                self._head = cur.next
                # 下一結點的向上指針指向None
                cur.next.prev = None
                return True
        # 移動指針查找元素
        while cur.next is not None:
            if cur.item == item:
                # 上一結點向下指針指向下一結點
                cur.prev.next = cur.next
                # 下一結點向上指針指向上一結點
                cur.next.prev = cur.prev
                return True
            cur = cur.next
        # 刪除元素在最后一個
        if cur.item == item:
            # 上一結點向下指針指向None
            cur.prev.next = None
            return True

    def find(self, item):
        """查找元素是否存在"""
        return item in self.items()

原文鏈接:https://blog.csdn.net/weixin_39589455/article/details/130504551

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新