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王道考研书

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

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

相关文章

【备忘】在Docker中安装宝塔面板,实现环境隔离,又能快速迁移服务器环境

我的环境是阿里云服务器&#xff08;新环境&#xff09; 【待继续】 【新方法】 我已经安装了docker&#xff0c;所以这里我先卸载。 卸载命令&#xff1a; sudo yum remove docker* containerd.io -y Docker默认保存位置是/var/lib/docker/&#xff0c;卸载Docker时&#x…

池化技术的深度解析与实践指南【大模型总结】

池化技术的深度解析与实践指南 池化技术作为计算机系统中的核心优化手段&#xff0c;通过资源复用和预分配机制显著提升系统性能。本文将从原理、实现到最佳实践&#xff0c;全方位剖析池化技术的核心要点&#xff0c;并结合实际案例说明其应用场景与调优策略。 一、池化技术的…

HCIP【BGP协议(详解)】

目录 1 BGP协议产生背景 2 BGP协议特性 2.1 自治系统间路由传播 2.2 路由矢量协议 2.3 防环机制 2.4 基于TCP传输 2.5 路由更新机制 2.6 丰富的路由属性 2.7 支持CIDR和路由聚合 2.8 路由过滤和策略控制 2.9 动态对等体功能 3 BGP基本术语 4 BGP规划问题 4.1 路…

VirtualBox 配置双网卡(NAT + 桥接)详细步骤

在 VirtualBox 中为 CentOS 虚拟机配置双网卡&#xff08;NAT 桥接&#xff09;&#xff0c;使其既能访问外网&#xff08;NAT&#xff09;&#xff0c;又能与宿主机&#xff08;Windows 10&#xff09;或局域网通信&#xff08;桥接&#xff09;。 步骤 1&#xff1a;关闭虚…

Upload-labs靶场通关

之前搭好了靶场&#xff0c;Upload-labs 靶场搭建 及一句话木马的原理与运用-CSDN博客 今天开始通关并写详细流程 Pass-1 来到靶场的第一关 先随便上传php 代码 点击上传 发现文件类型被限制了 方法1&#xff1a; 改文件后缀为合法文件&#xff08;.jpg .png .gif&#xf…

[GN] Python3基本数据类型 -- 与C的差异

Python3 面向对象 文章目录 Python3的基本数据类型6个标准的数据类型NumbersStringListtupleSetsDictionaries Python运算符逻辑 运算符成员运算符身份运算符 Python3 数字Python3 序列序列切片序列相加序列相乘序列相关内置函数 Python3 列表访问列表的值更新列表删除列表元素…

MCP over MQTT:EMQX 开启物联网 Agentic 时代

前言 随着 DeepSeek 等大语言模型&#xff08;LLM&#xff09;的广泛应用&#xff0c;如何找到合适的场景&#xff0c;并基于这些大模型构建服务于各行各业的智能体成为关键课题。在社区中&#xff0c;支持智能体开发的基础设施和工具层出不穷&#xff0c;其中&#xff0c;Ant…

AI助力高效PPT制作:从内容生成到设计优化

随着人工智能技术的不断发展&#xff0c;AI在各个领域的应用日益普及&#xff0c;尤其是在文档和演示文稿的创建过程中。PowerPoint&#xff08;PPT&#xff09;作为最常用的演示工具之一&#xff0c;借助AI的技术手段&#xff0c;可以极大地提高制作效率并提升最终呈现效果。在…

学透Spring Boot — 009. Spring Boot的四种 Http 客户端

目录 常见的HttpClient Spring 提供的HttpClient RestTemplate Spring 提供的模板类 XXXTemplate RestTemplate的使用 RestTemplate的使用技巧 RestTemplate的问题 RestClient RestClinet的基本使用 RestClient的自动配置 RestClient 序列化对象 异常处理 onStatus …

leetcode117 填充每个节点的下一个右侧节点指针2

LeetCode 116 和 117 都是关于填充二叉树节点的 next 指针的问题&#xff0c;但它们的区别在于 树的类型 不同&#xff0c;117与 116 题类似&#xff0c;但给定的树是 普通二叉树&#xff08;不一定完全填充&#xff09;&#xff0c;即某些节点可能缺少左或右子节点。 树的结构…

软考系统架构师 — 4 嵌入式软件

目录 4.1 考点分析 4.2 嵌入式微处理器 4.2.1嵌入式微处理器体系结构 5.2.2 嵌入式微处理器分类 4.2.3 多核处理器 4.3 嵌入式软件 4.4 嵌入式系统 4.4.1 嵌入式系统的组成 4.4.2 嵌入式系统分类 4.4.3 嵌入式数据库系统DBMS 4.4.4 嵌入式操作系统OS 4.4.5 嵌入式实…

RocketMQ 中的 ProducerManager 组件剖析

一、引言 在分布式系统的消息传递领域&#xff0c;RocketMQ 以其高性能、高可用性和强大的扩展性脱颖而出。ProducerManager 作为 RocketMQ 中的一个关键组件&#xff0c;在消息生产环节发挥着至关重要的作用。它负责管理消息生产者&#xff08;Producer&#xff09;的生命周期…

k8s进阶之路:本地集群环境搭建

概述 文章将带领大家搭建一个 master 节点&#xff0c;两个 node 节点的 k8s 集群&#xff0c;容器基于 docker&#xff0c;k8s 版本 v1.32。 一、系统安装 安装之前请大家使用虚拟机将 ubuntu24.04 系统安装完毕&#xff0c;我是基于 mac m1 的系统进行安装的&#xff0c;所…

深度学习数据集划分比例多少合适

在机器学习和深度学习中&#xff0c;测试集的划分比例需要根据数据量、任务类型和领域需求灵活调整。 1. 常规划分比例 通用场景 训练集 : 验证集 : 测试集 60% : 20% : 20% 适用于大多数中等规模数据集&#xff08;如数万到数十万样本&#xff09;&#xff0c;平衡了训练数…

【TS学习】(15)分布式条件特性

在 TypeScript 中&#xff0c;分布式条件类型&#xff08;Distributive Conditional Types&#xff09; 是一种特殊的行为&#xff0c;发生在条件类型作用于裸类型参数&#xff08;Naked Type Parameter&#xff09; 时。这种特性使得条件类型可以“分布”到联合类型的每个成员…

NSSCTF [HGAME 2023 week1]simple_shellcode

3488.[HGAME 2023 week1]simple_shellcode 手写read函数shellcode和orw [HGAME 2023 week1]simple_shellcode (1) motalymotaly-VMware-Virtual-Platform:~/桌面$ file vuln vuln: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpret…

PostgreSQL的扩展(extensions)-常用的扩展-pg_dirtyread

PostgreSQL的扩展&#xff08;extensions&#xff09;-常用的扩展-pg_dirtyread pg_dirtyread 是 PostgreSQL 的一个特殊扩展&#xff0c;它允许读取已被删除但尚未被 VACUUM 清理的数据行&#xff0c;是数据恢复的重要工具。 原理&#xff1a; pg_dirtyread 通过直接访问表的…

linux3 mkdir rmdir rm cp touch ls -d /*/

Linux 系统的初始目录结构遵循 FHS&#xff08;Filesystem Hierarchy Standard&#xff0c;文件系统层次标准&#xff09;&#xff0c;定义了每个目录的核心功能和存储内容。以下是 Linux 系统初始安装后的主要目录及其作用&#xff1a; 1. 核心系统目录 目录用途典型内容示例…

Bazel中的Symbol, Rule, Macro, Target, Provider, Aspect 等概念

学习Bazel &#xff0c;就要学习Bazel 的规则定义&#xff0c; 弄清各个概念是重要的一个步骤。 在 Bazel 规则定义中&#xff0c;Symbol、Rule 和 Macro 是常见的概念。除此之外&#xff0c;Bazel 还有 Target、Provider、Aspect Repository、Package、 Workspace、 Configura…