Python数据结构之双向循环链表

news/2025/3/10 11:39:07/文章来源:https://www.cnblogs.com/jackchen28/p/18635896

1、循环双向链表特点

  • 通过当前结点直接获取上一结点
  • 通过头结点的上一结点直接可以去找到尾结点
  • 可以进行反向循环链表,即反转链表

2、头结点

链表头:
在数据结构中,链表是一种常见的存储结构。链表的每个节点包含数据和指向下一个节点的指针。链表头是链表的第一个节点,它在链表的操作中起着重要的作用。

链表头的意义:
链表头节点是一个特殊的节点,它通常不存储实际数据,而是指向链表的第一个实际数据节点。链表头的主要作用是简化链表的操作,特别是在插入和删除节点时。通过引入头节点,可以避免处理链表第一个节点的特殊情况,使代码更加简洁和通用。

3、代码示例

class Node(object):# 节点类def __init__(self,item):self.item = item  # 记录数据self.next = None  # 记录下一个节点self.pre =  None  # 记录前面节点class DoubleCycLinkList(object):# 双链表类def __init__(self):# 所有操作都是从头开始,需要记录头结点self.__head = Nonedef is_empty(self):"""链表是否为空"""return self.__head is Nonedef length(self):"""链表长度"""if self.is_empty():return 0# 定义计数器,遍历链表count = 1cur = self.__headwhile cur.next is not self.__head:count += 1cur = cur.nextreturn countdef travel(self):"""遍历整个链表"""if self.is_empty():return# 定义游标,从头向尾移动cur = self.__headwhile cur.next is not self.__head:print(cur.item, end=" ")# 让游标往后移动cur = cur.next# while循环会漏掉尾节点print(cur.item)def add(self,item):"""链表头部添加元素"""# 创建新的节点node = Node(item)if self.is_empty():self.__head = nodenode.next = nodereturn# 遍历找到尾节点cur = self.__headwhile cur.next is not self.__head:cur = cur.next# while 循环结束,cur指向尾节点# 新节点的next指向原来的头节点node.next = self.__head# 原来的头结点指向新节点self.__head = node# 让尾节点指向新的头cur.next = self.__head# 新的头结点指向尾节点self.__head.pre = curdef append(self,item):""""链表尾部添加元素"""# 判断链表是否为空if self.is_empty():self.add(item)return# 第一步,找尾节点cur = self.__headwhile cur.next is not self.__head:# 首节点的pre是尾节点cur = cur.next# while 循环结束,cur指向尾节点# 第二步,尾节点指向新节点node = Node(item)# 尾节点指向新的节点cur.next = node# 新的节点的pre指向原尾节点node.pre = cur# 新节点指向头节点node.next = self.__head# 头结点的pre指向新节点self.__head.pre = nodedef insert(self,pos, item):"""指定位置添加元素"""if pos <=  0:self.add(item)elif pos >= self.length():self.append(item)else:# 1 定义下标,与游标同步变化index = 0cur = self.__headwhile index < (pos - 1):index += 1cur = cur.next# 循环结束后,cur指向pos前置节点-node = Node(item)# 2、让新节点的next指向pos位置的节点node.next = cur.next# 让pos位置的节点的pre指向新节点cur.next.pre = node# 3、让pos位置的前置节点指向新节点cur.next = node# 让新节点的pre指向pos的前置节点node.pre = curdef remove(self,item):"""删除节点"""if self.is_empty():return# 定义pre记录当前节点的前置节点pre = Nonecur = self.__headwhile cur.next is not self.__head:if cur.item == item:# 删除当前节点# 如果pre为空,删掉的是头 需要让尾节点指向新的头if pre is None:# 找到尾节点temp = self.__headwhile temp.next is not self.__head:temp = temp.next# while循环结束,temp指向尾节点# 头结点指向当前的下一个节点self.__head = cur.next# 当前的下一个节点指向头结点cur.next.pre = self.__head# 让尾节点指向新的头temp.next = self.__head# 新的头接点指向尾节点self.__head.pre = tempelse:# 删除中间节点# 上一个节点的next指向当前的的next即下一个节点pre.next = cur.nextcur.next.pre = cur.prereturn# pre 一直记录cur的前置节点pre = curcur = cur.next# while循环处理不了尾节点,单独处理尾节点if cur.item == item:# 如果pre为空,证明当前只有一个节点,而且要删除这个节点if pre is None:self.__head = Noneelse:# 让尾节点的前置节点指向头pre.next = self.__headself.__head.pre = cur.predef search(self,item):"""查找节点是否存在"""if self.is_empty():return Falsecur = self.__headwhile cur.next is not self.__head:if cur.item == item:return Truecur = cur.next# 单独处理尾节点if cur.item == item:return Truereturn Falseif __name__ == '__main__':sll = DoubleCycLinkList()print(sll.length())sll.add(1)sll.add(2)sll.add(3)print("11111===========")sll.travel()sll.append(4)sll.travel()print("=====")sll.remove(1)sll.travel()sll.remove(4)sll.travel()sll.remove(3)sll.travel()sll.insert(-10,0)sll.travel()sll.insert(10, 10)sll.travel()sll.insert(1, 1)sll.travel()print(sll.length())print("======")print(sll.search(0))print(sll.search(2))print(sll.search(10))print(sll.search(7))sll.travel()

参考:

https://blog.csdn.net/qq_33465047/article/details/104642601
https://blog.csdn.net/Winnie_boy/article/details/116163996
https://www.cnblogs.com/Lin-Yi/p/7326713.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/859877.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CDS标准视图:功能位置 I_FunctionalLocation

视图名称:I_FunctionalLocation 视图类型:基础 视图代码:点击查看代码 @EndUserText.label: Functional Location @Analytics: { dataCategory: #DIMENSION } @VDM.viewType: #BASIC @AbapCatalog: { sqlViewName: IFUNCTLLOCATION, compiler.compareFilter, preserveKey } …

DNS 原理入门

DNS 原理入门 导读 DNS 是互联网核心协议之一。不管是上网浏览,还是编程开发,都需要了解一点它的知识。本文详细介绍DNS的原理,以及如何运用工具软件观察它的运作。我的目标是,读完此文后,你就能完全理解DNS。一、DNS 是什么? DNS (Domain Name System 的缩写)的作用非…

Pycharm 2024.3 安装详细教程与激活方法(附常见问题解决)

Pycharm概述 Pycharm是JetBrains公司推出的一款功能强大的Python集成开发环境(IDE),凭借其丰富的功能和工具集,极大地提升了开发者的编程效率和工作体验。温馨提示: 本文中的方法仅供学习交流使用,如果条件允许,请支持正版软件。删除旧版本 Pycharm 如果您的电脑中已经安…

算法网关视频分析网关小知识:如何对视频分析系统实施冗余设计以提高稳定性?

在城市交通管理中,视频分析系统扮演着至关重要的角色,它不仅需要实时监控和分析交通流量,还需要在各种复杂环境下保持稳定运行。为了确保视频分析系统在面对设备故障、网络中断、电源波动等不可预见情况时仍能保持高可用性,实施冗余设计成为了提高系统稳定性的关键策略。以…

敏捷销售的基础:协同工具如何助力车企升级

今年来,国家在汽车产业领域频频出台利好政策,从新能源汽车补贴延续到以旧换新购车补贴,这一系列措施为汽车企业创造了全新的市场机遇。然而,面对复杂的销售网络、多样的营销活动和庞大的数据管理需求,车企如何迅速响应政策、提升协作效率,成为当前的核心挑战。 政策推动下…

在北大的第一学期结课小记——2024.12.27

本来是想昨天下午写的,因第一学期之课程在26日上午第四节课便已然完结,但却因个人的懒惰拖到了今日,我实在是罪无可恕,愿不要在接下来的期末复习上延续此般习气在开学初,本学期的选课方案可谓充满了妥协与权衡:为防掉课线代放弃了xsq,计概放弃了yhf,物院思修强制选课撞…

工作坊报名|使用 TEN Framework 与 Azure,探索你的多模态交互新场景

活动背景 GPT-4o Realtime API 发布,语音 AI 正在进入一场新的爆发。AI 的实时语音和视觉互动能力将为我们带来更多全新创意和应用场景。实时音频交互:允许应用程序实时接收并响应语音和文本输入。 自然语音生成:减少 AI 语音的机械感,使对话更加人性化。 多语言能力:促进…

【2】UDS诊断的请求和响应

1. 常见的UDS服务 UDS共包含6大类,26个服务。其中常用的有:诊断和通信管理中的10(诊断会话控制)、11(ECU 复位)、27(安全访问)、3E(待机握手),数据传输功能中的22(通过ID读数据)、2E(通过ID写数据),存储数据传输功能的14(清除诊断信息)、19(读取故障码信息)…

学习破解一个Android程序

首先编写一个android测试程序 功能:校验用户名和注册码,成功则弹出注册成功提示 以下仅给出关键部分的代码 res/layout/activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.androi…

DP1363F是一款高度集成的非接触读写芯片,高性能、多协议NFC读卡IC

DP1363F是一款高度集成的非接触读写芯片,集强大的多协议支持、最高射频输出功率,以及突破性技术低功耗卡片检测等优势于一身,满足市场对更高集成度、更小外壳和互操作性的需求,适用于银行、电子政务、交通、移动支付等众多基础设施应用。 DP1363F支持下列操作模式: •读写模…

ASP.NET Core 中的速率限制中间件的使用

简介 在ASP.NET Core中,速率限制中间件是用来控制客户端对Web API或MVC应用程序发出请求的速率,以防止服务器过载和提高安全性。 下面是 AddRateLimiter 的一些基本用法: 1. 注册服务 在 Startup.cs 或 Program.cs 中,需要注册 AddRateLimiter 服务。这可以通过以下代码完成…

java 使用HttpClient发送@RequestBody类型的请求(解决中文乱码)

如何使用java发送参数以@RequestBody类型接收到的请求。如下使用java的HttpClient写一个样例 依赖<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.10</version> </dep…