IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Python数据结构与算法_10_双向链表 -> 正文阅读

[数据结构与算法]Python数据结构与算法_10_双向链表

前情提要:Python数据结构与算法_8_链表、无序链表

前情提要:Python数据结构与算法_9_有序链表


什么是双向链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。——《百度百科对于双向链表的解释》

双向链表是在单向链表的基础上扩展而成的更为复杂的数据结构,双向链表其中的每个节点除了含有自身数据元素之外,还含有两个链接(以prev与next为例),分别指向它的上一个节点与下一个节点

  • prev 链接指向前一个节点,当此节点为第一个节点时,则 prev 链接指向None。
  • next 链接指向下一个节点,当此节点为最后一个节点时,则 next 链接指向None。

图例则如下所示:
在这里插入图片描述

双向链表适用于需要双向查找节点值的场景中,在数据量难以估计并且数据增删操作频繁的场景中,双向链表有一定优势;链表在内存中呈现的状态是离散的地址块,不需要像列表一样预先分配连续的内存空间,在内存的充分利用上更胜一筹,不过增加了一些额外开销。


双向链表的实现

首先需要构造节点,由于引入了前驱和后继两个指针,所以节点相比单链表也发生了变化,实现代码如下。

class DNode:
    def __init__(self, initdata):
        self.data = initdata
        self.prev = None
        self.next = None
    
    def getData(self):
        return self.data
    
    def getNext(self):
        return self.next
    
    def getPrev(self):
        return self.prev
    
    def set Data(self, newdata):
        self.data = new data
        
    def setNext(self, newnext):
        self.next = newnext

    def setPrev(self, newprev):
        self.prev = newprev

然后我们实现双向链表构造方法,仍然是链表头指向None,代码如下:

class DLinkList:
    def __init__(self):
        self.head = None

下面我们来实现双向链表的三个基本方法,即判断链表是否为空(isEmpty()),以及得到链表长度(节点个数)(length()),还有搜索链表中的元素(search())。双向链表的这三个基本方法与单链表是相同的,并没有发生变化。

class DLinkList:
    def isEmpty(self):
        return self.head == None
    
    def length(self):
        current = self.head
        count = 0
        while current != None:
            count = count + 1
            current = current.getNext()
        
        return count
    
    def search(self, item):
        current = self.head
        found = False
        while current != None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

实现 add 方法,链表头部插入节点:

class DLinkList:
    def add(self, item):
        temp = DNode(item)
        if self.head == None:
            self.head = Node
        else:
            temp.setNext(self.head)
            self.head.setPrev(temp)
            self.head = temp

实现 append 方法,链表尾部插入节点:

class DLinkList:
    def append(self, item):
        temp = DNode(item)
        if self.head == None:
            self.head = Node
        else:
            current = self.head
            while current.getNext() != None:
                current = current.getNext()
            current.setNext(temp)
            temp.setPrev(current)

实现 insert 方法,链表指定位置插入节点:

class DLinkList:
    def insert(self, pos, item):
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            temp = Node(item)
            current = self.head
            count = 0
            # 移动到指定位置的前一个位置 因为实际控制的是指定位置的上一个节点
            while count < (pos-1):
                count = count + 1
                current = current.getNext()
                
            # 将temp的prev 指向当前节点
            temp.setPrev(current)
            # 将temp的next 指向当前节点的下一个节点
            temp.setNext(current.getNext())
            # 将当前节点的下一个节点的prev 指向temp
            current.getNext().setPrev(temp)
            # 将当前节点的next 指向temp
            current.setNext(temp)

insert 方法过程图示如下:
在这里插入图片描述

实现 remove 方法,移除链表中的某个节点:

class DLinkList:
    def remove(self, item):
        if self.head == None:
            return False
        else:
            current = self.head
            # 如果首节点的元素即是要删除的元素
            if current.getData() == item:
                # 如果链表只有这一个节点
                if current.getNext() == None:
                    self.head = None
                else:
                    # 将第二个节点的prev设置为None
                    current.getNext().setPrev(None)
                    # 将链表头head指向第二个节点
                    self.head = current.getNext()
                return True
            
            # 循环遍历寻找目标节点
            while current != None:
                # 寻找到目标节点
                if current.getData() == item:
                    # 将当前节点的前一个节点的next 指向 当前节点的后一个节点
                    current.getPrev().setNext(current.getNext())
                    # 将当前节点的后一个节点的prev 指向 当前节点的前一个节点
                    current.getNext().setPrev(current.getPrev())
                    return True
                current = current.getNext()
            
            return False
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:03:13  更:2022-03-13 22:06:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:23:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码