当前位置: 首页 > article >正文

26考研——线性表_ 线性表的链式表示_双循环链表(2)

408答疑


文章目录

  • 三、 线性表的链式表示
    • 双循环链表
      • 单链表与双链表的比较
        • 单链表的特点
        • 双链表的特点
      • 双链表上基本操作的实现
        • 双链表的插入操作
        • 双链表的删除操作
      • 双链表的代码实操
        • 定义结点
        • 创建一个结点
        • 带头结点的双链表初始化
        • 创建双链表
        • 打印双链表
        • 查找结点
        • 插入结点
          • 在指定节点后插入新节点
          • 在指定节点前插入新节点
        • 删除结点
        • 反转链表
        • 排序链表
      • 循环链表
        • 循环单链表
          • 操作描述
          • 操作特点
        • 循环双链表
      • 链表的分类
  • 五、参考资料
    • 鲍鱼科技课件
    • 26王道考研书


三、 线性表的链式表示

双循环链表

单链表与双链表的比较

单链表的特点
  • 单链表结点中只有一个指向其后继的指针,使得单链表只能从前往后依次遍历。
  • 访问某个结点的前驱(插入、删除操作时),只能从头开始遍历,访问前驱的时间复杂度为 O ( n ) O(n) O(n)
  • 为了克服单链表的这个缺点,引入了双链表。
双链表的特点
  • 双链表结点中有两个指针 priornext,分别指向其直接前驱和直接后继,如下图所示。表头结点的 prior 域和尾结点的 next 域都是 NULL

在这里插入图片描述

  • 双链表在单链表结点中增加了一个指向其前驱的指针 prior,因此双链表的按值查找和按位查找的操作与单链表的相同。但双链表在插入和删除操作的实现上,与单链表有着较大的不同。这是因为“链”变化时也需要对指针 prior 做出修改,其关键是保证在修改的过程中不断链。此外,双链表可以很方便地找到当前结点的前驱,因此,插入、删除操作的时间复杂度仅为 O ( 1 ) O(1) O(1)

双链表上基本操作的实现

双链表的插入操作
  • 在双链表中 p 所指的结点之后插入结点 *s,其指针的变化过程如图所示。

在这里插入图片描述

  • 插入操作的步骤如下:

    1. s->next 指向 p->next
    2. p->next->prior 指向 s
    3. s->prior 指向 p
    4. p->next 指向 s
  • 上述代码的语句顺序不是唯一的,但也不是任意的。步骤 1 必须在步骤 4 之前,否则 *p 的后继结点的指针就会丢失,导致插入失败。

双链表的删除操作
  • 删除双链表中结点 *p 的后继结点 *q,其指针的变化过程如图所示。

在这里插入图片描述

  • 删除操作的步骤如下:

    1. p->next 指向 q->next
    2. q->next->prior 指向 p
    3. 释放 q 结点空间

双链表的代码实操

定义结点
  • 定义双链表的节点类型,包括数据域、前驱指针和后继指针。
typedef struct DCListNode {ElemType data;          // 数据域struct DCListNode *prev; // 前驱指针struct DCListNode *next; // 后继指针
} DCListNode, *DCLinkList;
创建一个结点
  • 创建并初始化一个新的双链表节点。
DCListNode* buyNode(ElemType x) {DCListNode *s = (DCListNode*)malloc(sizeof(DCListNode));s->data = x;return s;
}
带头结点的双链表初始化
  • 初始化一个带头结点的双链表。
void initDCList(DCListNode **head) {*head = (DCListNode*)malloc(sizeof(DCListNode));(*head)->prev = *head;(*head)->next = *head;
}
创建双链表
  • 根据给定数组创建一个双链表。
void createDCList(DCLinkList DCL, ElemType ar[], int n) {DCListNode *p = DCL;for (int i = 0; i < n; ++i) {DCListNode *s = (DCListNode*)malloc(sizeof(DCListNode));s->data = ar[i];s->prev = p->prev;s->next = p;p->prev->next = s;p->prev = s;}
}
打印双链表
  • 从头结点的下一个节点开始,打印链表中的每个节点数据,直到回到头结点。
void printDCList(DCLinkList DCL) {DCListNode *p = DCL->next;while (p != DCL) {printf("%d-->", p->data);p = p->next;}printf("Over.\n");
}
查找结点
  • 从头结点开始,遍历链表直到找到目标节点或到达头结点。
DCListNode* findDCNode(DCLinkList DCL, ElemType key) {DCListNode *p = DCL->next;while (p != DCL && p->data != key)p = p->next;if (p != DCL)return p; // 找到了节点return NULL;  // 没有找到节点
}
插入结点
在指定节点后插入新节点
  • 在双链表中指定节点 pos 之后插入一个新节点 x。
void insertDCNodeBack(DCLinkList DCL, DCListNode *pos, ElemType x) {DCListNode *s = buyNode(x);s->prev = pos;s->next = pos->next;s->next->prev = s;s->prev->next = s;
}
在指定节点前插入新节点
  • 在双链表中指定节点 pos 之前插入一个新节点 x。
void insertDCNodeFront(DCLinkList DCL, DCListNode *pos, ElemType x) {DCListNode *s = buyNode(x);s->prev = pos->prev;s->next = pos;s->next->prev = s;s->prev->next = s;
}
删除结点
  • 找到目标节点,调整前后节点的指针并释放目标节点。
void deleteDCNode(DCLinkList DCL, ElemType key) {DCListNode *p = findDCNode(DCL, key);if (p == NULL)return; // 删除失败p->prev->next = p->next;p->next->prev = p->prev;free(p);
}
反转链表
  • 逐个摘除链表中的节点并重新插入到链表头部。
void reverseDCList(DCLinkList DCL) {DCListNode *p = DCL->next;DCListNode *q = p->next;p->next = DCL;DCL->prev = p;while (q != DCL) {p = q;q = q->next;p->next = DCL->next;p->prev = DCL;p->prev->next = p;p->next->prev = p;}
}
排序链表
  • 逐个摘除链表中的节点并按顺序插入到链表中。
void sortDCList(DCLinkList DCL) {DCListNode *p = DCL->next;DCListNode *q = p->next;p->next = DCL;DCL->prev = p;while (q != DCL) {p = q;q = q->next;DCListNode *cur = DCL->next;while (cur != DCL && p->data > cur->data)cur = cur->next;p->next = cur;p->prev = cur->prev;p->prev->next = p;p->next->prev = p;}
}

循环链表

循环单链表
  • 循环单链表的特点是最后一个结点的 next 指针指向头结点,形成一个环。这种结构使得链表可以从任意位置开始遍历,而不必担心到达链表的末尾,如下图所示。

在这里插入图片描述

  • 特点
    • 表尾结点的 next 域指向头结点。
    • 判空条件不是头结点的指针是否为空,而是它是否等于头指针 L
操作描述
  • 循环单链表的插入、删除算法与单链表的几乎一样,所不同的是,若操作是在表尾进行,则执行的操作不同,以让单链表继续保持循环的性质。这是因为循环单链表是一个“环”,所以在任何位置上的插入和删除操作都是等价的,而无须判断是否是表尾。
操作特点
  • 在单链表中只能从表头结点开始往后顺序遍历整个链表,而循环单链表可以从表中的任意一个结点开始遍历整个链表。
  • 有时对循环单链表不设头指针而仅设尾指针,以使得操作效率更高。其原因是,若设的是头指针,对在表尾插入元素需要 O ( n ) O(n) O(n) 的时间复杂度,而若设的是尾指针 rr->next 即头指针,对在表头或表尾插入元素都只需要 O ( 1 ) O(1) O(1) 的时间复杂度。
循环双链表
  • 循环双链表在循环单链表的基础上增加了一个指向前驱的指针 prior,使得链表可以从任意结点向前或向后遍历,如下图所示。

在这里插入图片描述

  • 特点
    • 头结点的 prior 指针指向表尾结点。
    • 尾结点的 next 指针指向头结点。
    • 判空条件是头结点的 priornext 域都等于 L

链表的分类

  • 循环链表可以是单链表或双链表,可以带头结点或不带头结点,也可以是循环的或非循环的( 2 3 2^3 23种可能性)。这三种特性可以组合出八种不同的链表类型,如下图所示。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

五、参考资料

鲍鱼科技课件

b站免费王道课后题讲解:
在这里插入图片描述

网课全程班:
在这里插入图片描述

26王道考研书

相关文章:

26考研——线性表_ 线性表的链式表示_双循环链表(2)

408答疑 文章目录 三、 线性表的链式表示双循环链表单链表与双链表的比较单链表的特点双链表的特点 双链表上基本操作的实现双链表的插入操作双链表的删除操作 双链表的代码实操定义结点创建一个结点带头结点的双链表初始化创建双链表打印双链表查找结点插入结点在指定节点后插…...

大模型如何引爆餐饮与电商行业变革

大模型如何引爆餐饮与电商行业变革&#xff1f; 一、时代背景&#xff1a;大模型重构产业逻辑的底层动力 1. 技术跃迁催生效率革命 2025年&#xff0c;大模型技术迎来"普惠临界点"。李开复在中关村论坛指出&#xff0c;大模型推理成本每年降低10倍&#xff0c;使得…...

基于springboot的考研成绩查询系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 这些年随着Internet的迅速发展&#xff0c;我们国家和世界都已经进入了互联网大数据时代&#xff0c;计算机网络已经成为了整个社会以及经济发展的巨大动能&#xff0c;考研成绩查询管理事务现在已经成为社会关注的重要内容&#xff0c;因此运用互联网技术来提高考研成绩…...

es自定义ik分词器中文词库实现热更新

基于web地址的方式实现ik分词热更新。 操作系统&#xff1a;win 11 es version&#xff1a;8.6.2 ik version&#xff1a;8.6.2 1、创建web服务&#xff0c;并提供ik查询词库接口 编写分词http url代码&#xff0c;返回自定义分词内容分词词库数据来自业务需求&#xff0c;存…...

OpenStack 卷虚拟机跨租户迁移方案

目标&#xff1a;迁移租户A的卷虚机到租户B 场景&#xff1a;使用卷虚拟机&#xff0c;租户a和b使用相同网络 租户A的操作&#xff1a; 1.记录虚拟机的ip地址&#xff0c;Mac信息&#xff0c; nova interface-list neutron port-show 2.对虚拟机进行关机操作&#xff0c;将…...

添加购物车功能

业务需求&#xff1a; 用户提交三个字段&#xff0c;服务端根据提交的字段判断是菜品还是套餐&#xff0c;根据菜品或者套餐添加购物车表中。 代码实现 RestController Slf4j RequestMapping("/user/shoppingCart") public class ShoppingCartController {Autowired…...

Logo语言的系统监控

Logo语言的系统监控 引言 在信息技术飞速发展的时代&#xff0c;系统监控成为了确保计算机系统和网络平稳运行的重要手段。系统监控不仅可以实时跟踪系统的性能、资源使用情况和安全风险等&#xff0c;还能够在出现问题时及时发出警报&#xff0c;从而避免潜在的故障和损失。…...

Scheme语言的算法

Scheme语言的算法探索 引言 Scheme是一种以表达式为基础的编程语言&#xff0c;属于Lisp家族&#xff0c;因其简洁、灵活的语法而受到广泛关注。Scheme不仅适合教学&#xff0c;还被用于实际应用开发和研究。本文将深入探讨Scheme语言的算法&#xff0c;包括其基本特性、常用…...

Python爬虫第2节-网页基础和爬虫基本原理

目录 一、网页基础 1.1 网页的组成 1.2 网页的结构 1.3 节点树及节点间的关系 1.4 选择器 二、爬虫的基本原理 2.1 爬虫概述 2.2 能抓怎样的数据 2.3 JavaScript 渲染页面 一、网页基础 使用浏览器访问网站时&#xff0c;我们会看到各式各样的页面。你是否思考过&…...

阿里巴巴langengine二次开发大模型平台

阿里巴巴LangEngine开源了&#xff01;支撑亿级网关规模的高可用Java原生AI应用开发框架 - Leepy - 博客园 阿里国际AI应用搭建平台建设之路(上) - 框架篇 基于java二次开发 目前Spring ai、spring ai alibaba 都是java版本的二次基础能力 重要的是前端工作流 如何与 服务端的…...

深度学习中的 Batch 机制:从理论到实践的全方位解析

一、Batch 的起源与核心概念 1.1 批量的中文译名解析 Batch 在深度学习领域标准翻译为"批量"或"批次"&#xff0c;指代一次性输入神经网络进行处理的样本集合。这一概念源自统计学中的批量处理思想&#xff0c;在计算机视觉先驱者Yann LeCun于1989年提出…...

【网络协议】三次握手与四次挥手

例如我们使用MobaXterm登录服务器的时候&#xff0c;基于TCP协议的之间是如何进行通信的&#xff1f; 使用工具&#xff1a;wireshark抓取传输层TCP协议 三次握手 mobaxterm&#xff1a;登录服务器触发三次握手 wireshark过滤分析 ip.addr 192.168.3.239 192.168.3.239登录…...

请求被中止: 未能创建 SSL/TLS 安全通道。

需要安装vs2019社区办&#xff0c;下载VisualStudioSetup.exe后&#xff0c;报无法从"https://aka,ms/vs/16/release/channel"下载通道清单错误&#xff0c;接着打开%temp%目录下的最新日志&#xff0c;发现日志里报&#xff1a; [27d4:000f][2025-04-04T21:15:43] …...

JS API

const变量优先 即对象、数组等引用类型数据可以用const声明 API作用和分类 DOM (ducument object model) 操作网页内容即HTML标签的 树状模型 HTML中标签 JS中对象 最大对象 document 其次大 html 以此类推 获取DOM对象 CSS 中 使用选择器 JS 中 选多个 时代的眼泪 修…...

“一路有你”公益行携手《东方星动》走进湖南岳阳岑川镇中心小学

2025年4月2日&#xff0c;“一路有你”公益行携手《东方星动》走进湖南岳阳岑川镇&#xff0c;一场充满爱与温暖的捐赠仪式在岑川镇中心小学隆重举行。这是一场跨越千里的爱心捐赠&#xff0c;也是一场别开生面的国防教育&#xff0c;更是一场赋能提质的文化盛宴。 岑川镇地处湘…...

vue组件开发:什么是VUE组件?

什么是VUE组件 在我们实际开发过程中你也许会发现有很多代码是重复的&#xff0c;它们可能是一个按钮、一个表单、一个列表等等&#xff0c;其中最为显著的应该是列表。 以CSDN的首页为例&#xff1a; 上述截图中的文章列表可能会在多处出现&#xff0c;比如此截图是精选博客…...

仿小红书社交源码+及时通讯聊天软件APP源码

多端支持&#xff0c;数据互通 本程序支持H5、小程序、安卓、iOS四端运行&#xff0c;共用同一套后台管理系统&#xff0c;确保数据同步&#xff0c;用户可在不同设备上无缝切换&#xff0c;实现真正的多端互通。 技术架构 前端技术&#xff1a;Vue2、uni-app、HTML、CSS、Jav…...

Libevent TCP开发指南

一、概念 Libevent 提供了高效的 TCP 网络编程接口,使开发者能够轻松构建高性能的 TCP 服务器和客户端。本指南将详细介绍如何使用 Libevent 进行 TCP 网络开发。 核心组件 事件基 (event_base) - 事件处理的核心结构 事件 (event) - 表示单个事件 缓冲区事件 (bufferevent)…...

Objective-C语言的集合

Objective-C语言的集合 引言 Objective-C是一种面向对象的编程语言&#xff0c;主要用于苹果的macOS和iOS系统应用程序的开发。作为C语言的一个超集&#xff0c;Objective-C继承了C语言的优雅&#xff0c;同时又添加了许多强大的特性&#xff0c;使其适合于大型项目的开发。在…...

网络安全与防护策略

随着互联网的普及与信息化程度的不断加深&#xff0c;网络安全问题已成为全球关注的焦点。从个人用户到大规模的企业系统&#xff0c;网络安全威胁的不断演变和升级已成为每个人和组织不可忽视的挑战。无论是恶意软件、钓鱼攻击&#xff0c;还是数据泄露、拒绝服务攻击&#xf…...

OpenCV:计算机视觉的强大开源库

文章目录 引言一、什么是OpenCV&#xff1f;1.OpenCV的核心特点 二、OpenCV的主要功能模块1. 核心功能&#xff08;Core Functionality&#xff09;2. 图像处理&#xff08;Image Processing&#xff09;3. 特征检测与描述&#xff08;Features2D&#xff09;4. 目标检测&#…...

Java基础:面向对象进阶(二)

01-static static修饰成员方法 static注意事项&#xff08;3种&#xff09; static应用知识&#xff1a;代码块 static应用知识&#xff1a;单列模式 02-面向对象三大特征之二&#xff1a;继承 什么是继承&#xff1f; 使用继承有啥好处? 权限修饰符 单继承、Object类 方法重…...

【MVP 和 MVVM 相比 MVC 有哪些优化点?】

MVP 和 MVVM 相比 MVC 的优化及原因 1. MVC 的痛点 在传统 MVC 模式中&#xff1a; 视图&#xff08;View&#xff09;和模型&#xff08;Model&#xff09;直接交互&#xff1a;View 可能直接监听 Model 的变化&#xff08;如观察者模式&#xff09;&#xff0c;导致耦合。…...

ttkbootstrap 实现日期选择器, 开始和结束时间

ttkbootstrap 实现日期选择器&#xff0c; 开始和结束时间 1. 展示 2. 打印 3. 源码 from datetime import datetime import ttkbootstrap as ttkclass DateTimeEntryStart(ttk.Frame):def __init__(self, masterNone, **kwargs):super().__init__(master, **kwargs)self.dat…...

Vulnhub-PrinkysPalacev3

Vulnhub-PrinkysPalacev3 1、主机发现 arp-scan -l 扫描同网段 2、端口扫描 nmap -sS -sV 192.168.66.185 nmap -sS -A -T4 -p- 192.168.66.185 nmap --scriptvuln 192.168.66.185 PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.0.8 or later 5555/tcp o…...

matlab从pytorch中导入LeNet-5网络框架

文章目录 一、Pytorch的LeNet-5网络准备二、保存用于导入matlab的model三、导入matlab四、用matlab训练这个导入的网络 这里演示从pytorch的LeNet-5网络导入到matlab中进行训练用。 一、Pytorch的LeNet-5网络准备 根据LeNet-5的结构图&#xff0c;我们可以写如下结构 import…...

淘宝商品数据爬取与分析

淘宝商品数据爬取与分析是一个涉及网络爬虫技术和数据分析方法的过程&#xff0c;以下是其主要步骤&#xff1a; 数据爬取 确定爬取目标&#xff1a;明确要爬取的淘宝商品类别、具体商品名称或关键词等&#xff0c;例如想要分析智能手机市场&#xff0c;就以 “智能手机” 为…...

Spring Boot向Vue发送消息通过WebSocket实现通信

注意&#xff1a;如果后端有contextPath&#xff0c;如/app&#xff0c;那么前端访问的url就是ip:port/app/ws 后端实现步骤 添加Spring Boot WebSocket依赖配置WebSocket端点和消息代理创建控制器&#xff0c;使用SimpMessagingTemplate发送消息 前端实现步骤 安装sockjs-…...

Django4.0的快速查询以及分页

1. filter 方法 filter 是 Django ORM 中最常用的查询方法之一。它用来根据给定的条件过滤查询集并返回满足条件的对象。 articles Article.objects.all() # 使用 SearchFilter 进行搜索 search_param request.query_params.get(search, None) author_id request.query_pa…...

LangChain/Eliza框架在使用场景上的异同,Eliza通过配置实现功能扩展的例子

LangChain与Eliza框架的异同分析 ‌一、相同点‌ ‌模块化架构设计‌ 两者均采用模块化设计&#xff0c;支持灵活扩展和功能组合。LangChain通过Chains、Agents等组件实现多步骤任务编排‌&#xff0c;Eliza通过插件系统和信任引擎实现智能体功能的动态扩展‌。模块化特性降低…...