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

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

數(shù)據(jù)結(jié)構(gòu)——鏈表(python版)

作者:別出BUG求求了 更新時(shí)間: 2023-11-13 編程語(yǔ)言

一、鏈表簡(jiǎn)介

鏈表是一種在存儲(chǔ)單元上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu)。數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)。鏈表是由一系列的結(jié)點(diǎn)組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。每個(gè)結(jié)點(diǎn)包含兩部分:數(shù)據(jù)域與指針域。數(shù)據(jù)域存儲(chǔ)數(shù)據(jù)元素,指針域存儲(chǔ)下一結(jié)點(diǎn)的指針。

二、單向鏈表

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

鏈表失去了序列的隨機(jī)讀取優(yōu)點(diǎn),同時(shí)鏈表增加了指針域,空間開(kāi)銷(xiāo)也較大,但它對(duì)存儲(chǔ)空間的使用要相對(duì)靈活。

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

1. 定義結(jié)點(diǎn)

結(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)為數(shù)據(jù)元素(item)與 指針(next)

class Node(object):
    """單鏈表的結(jié)點(diǎn)"""

    def __init__(self, item):
        # item存放數(shù)據(jù)元素
        self.item = item
        # next是下一個(gè)節(jié)點(diǎn)的標(biāo)識(shí)
        self.next = None

2. 定義鏈表

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

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

    def __init__(self):
        self._head = None

示例:創(chuàng)建鏈表

if __name__ == '__main__':
    # 創(chuàng)建鏈表
    link_list = SingleLinkList()
    # 創(chuàng)建結(jié)點(diǎn)
    node1 = Node(1)
    node2 = Node(2)

    # 將結(jié)點(diǎn)添加到鏈表
    link_list._head = node1
    # 將第一個(gè)結(jié)點(diǎn)的next指針指向下一結(jié)點(diǎn)
    node1.next = node2

    # 訪問(wèn)鏈表
    print(link_list._head.item)  # 訪問(wèn)第一個(gè)結(jié)點(diǎn)數(shù)據(jù)
    print(link_list._head.next.item)  # 訪問(wèn)第二個(gè)結(jié)點(diǎn)數(shù)據(jù)

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

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

代碼如下:

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

    def __init__(self):
        self._head = None

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

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

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

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

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

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

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

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

示例:操作鏈表

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

三、循環(huán)鏈表

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

1. 循環(huán)鏈表結(jié)點(diǎn)

class Node(object):
    """鏈表的結(jié)點(diǎn)"""

    def __init__(self, item):
        # item存放數(shù)據(jù)元素
        self.item = item
        # next是下一個(gè)節(jié)點(diǎn)的標(biāo)識(shí)
        self.next = None

2. 定義循環(huán)鏈表

class SingleCycleLinkList(object):

    def __init__(self):
        self._head = None

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

    def length(self):
        """鏈表長(zhǎng)度"""
        # 鏈表為空
        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):
        """ 頭部添加結(jié)點(diǎn)"""
        node = Node(item)
        if self.is_empty():  # 為空
            self._head = node
            node.next = self._head
        else:
            # 添加結(jié)點(diǎn)指向head
            node.next = self._head
            cur = self._head
            # 移動(dòng)結(jié)點(diǎn),將末尾的結(jié)點(diǎn)指向node
            while cur.next != self._head:
                cur = cur.next
            cur.next = node
        # 修改 head 指向新結(jié)點(diǎn)
        self._head = node

    def append(self, item):
        """尾部添加結(jié)點(diǎn)"""
        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
            # 尾部指針指向新結(jié)點(diǎn)
            cur.next = node
            # 新結(jié)點(diǎn)指針指向head
            node.next = self._head

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

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

                    pre = cur  # 記錄前一個(gè)指針
                    cur = cur.next  # 調(diào)整指針位置
        # 當(dāng)刪除元素在末尾
        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())

四、雙向鏈表

雙向鏈表比單向鏈表更加復(fù)雜,它每個(gè)節(jié)點(diǎn)有兩個(gè)鏈接:一個(gè)指向前一個(gè)節(jié)點(diǎn),當(dāng)此節(jié)點(diǎn)為第一個(gè)節(jié)點(diǎn)時(shí),指向空值;而另一個(gè)鏈接指向下一個(gè)節(jié)點(diǎn),當(dāng)此節(jié)點(diǎn)為最后一個(gè)節(jié)點(diǎn)時(shí),指向空值。

在這里插入圖片描述

head 保存首地址,item 存儲(chǔ)數(shù)據(jù),next 指向下一結(jié)點(diǎn)地址,prev 指向上一結(jié)點(diǎn)地址。

1. 定義雙向鏈表結(jié)點(diǎn)

class Node(object):
    """雙向鏈表的結(jié)點(diǎn)"""

    def __init__(self, item):
        # item存放數(shù)據(jù)元素
        self.item = item
        # next 指向下一個(gè)節(jié)點(diǎn)的標(biāo)識(shí)
        self.next = None
        # prev 指向上一結(jié)點(diǎn)
        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):
        """鏈表長(zhǎng)度"""
        # 初始指針指向head
        cur = self._head
        count = 0
        # 指針指向None 表示到達(dá)尾部
        while cur is not None:
            count += 1
            # 指針下移
            cur = cur.next
        return count

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

    def add(self, item):
        """向鏈表頭部添加元素"""
        node = Node(item)
        if self.is_empty():
            # 頭部結(jié)點(diǎn)指針修改為新結(jié)點(diǎn)
            self._head = node
        else:
            # 新結(jié)點(diǎn)指針指向原頭部結(jié)點(diǎn)
            node.next = self._head
            # 原頭部 prev 指向 新結(jié)點(diǎn)
            self._head.prev = node
            # head 指向新結(jié)點(diǎn)
            self._head = node

    def append(self, item):
        """尾部添加元素"""
        node = Node(item)
        if self.is_empty():  # 鏈表無(wú)元素
            # 頭部結(jié)點(diǎn)指針修改為新結(jié)點(diǎn)
            self._head = node
        else:  # 鏈表有元素
            # 移動(dòng)到尾部
            cur = self._head
            while cur.next is not None:
                cur = cur.next
            # 新結(jié)點(diǎn)上一級(jí)指針指向舊尾部
            node.prev = cur
            # 舊尾部指向新結(jié)點(diǎn)
            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
            # 新結(jié)點(diǎn)的向下指針指向當(dāng)前結(jié)點(diǎn)
            node.next = cur
            # 新結(jié)點(diǎn)的向上指針指向當(dāng)前結(jié)點(diǎn)的上一結(jié)點(diǎn)
            node.prev = cur.prev
            # 當(dāng)前上一結(jié)點(diǎn)的向下指針指向node
            cur.prev.next = node
            # 當(dāng)前結(jié)點(diǎn)的向上指針指向新結(jié)點(diǎn)
            cur.prev = node

    def remove(self, item):
        """ 刪除結(jié)點(diǎn) """
        if self.is_empty():
            return
        cur = self._head
        # 刪除元素在第一個(gè)結(jié)點(diǎn)
        if cur.item == item:
            # 只有一個(gè)元素
            if cur.next is None:
                self._head = None
                return True
            else:
                # head 指向下一結(jié)點(diǎn)
                self._head = cur.next
                # 下一結(jié)點(diǎn)的向上指針指向None
                cur.next.prev = None
                return True
        # 移動(dòng)指針查找元素
        while cur.next is not None:
            if cur.item == item:
                # 上一結(jié)點(diǎn)向下指針指向下一結(jié)點(diǎn)
                cur.prev.next = cur.next
                # 下一結(jié)點(diǎn)向上指針指向上一結(jié)點(diǎn)
                cur.next.prev = cur.prev
                return True
            cur = cur.next
        # 刪除元素在最后一個(gè)
        if cur.item == item:
            # 上一結(jié)點(diǎn)向下指針指向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

  • 上一篇:沒(méi)有了
  • 下一篇:沒(méi)有了
欄目分類(lèi)
最近更新