[数据结构]无头单向非循环链表的实现与应用

文章目录

  • 一、引言
  • 二、线性表的基本概念
    • 1、线性表是什么
    • 2、链表与顺序表的区别
    • 3、无头单向非循环链表
  • 三、无头单向非循环链表的实现
    • 1、结构体定义
    • 2、初始化
    • 3、销毁
    • 4、显示
    • 5、增删查改
  • 四、分析无头单向非循环链表
    • 1、存储方式
    • 2、优点
    • 3、缺点
  • 五、总结
    • 1、练习题
    • 2、源代码

一、引言

在踏入编程的奇幻世界时,我们常常会遇到各种奇妙的数据结构,它们如同搭建宏伟城堡的砖石,不可或缺。而要想深入理解无头单向非循环链表这一复杂而强大的数据结构,首先得从它的基石 —— 线性表的基本概念开始。本文将分为两大篇章,第一篇章将带你漫步于线性表的瑰丽花园,探索其本质与奥秘;第二篇章则将引领你穿越无头单向非循环链表的迷雾,领略其实现与应用的壮丽风景。

对于指针和数组还感到迷茫的朋友,这里有一个精心准备的传送门,它将是你探索这些基石概念的得力助手。请放心,一旦你掌握了这些基础知识,无头单向非循环链表的神秘面纱将不再难以揭开。


二、线性表的基本概念

1、线性表是什么

想象一下,你手中握着一串璀璨的珍珠项链,每一颗珍珠都紧紧相连,形成一个有序的整体。这就是线性表的生动写照。线性表,简单来说,就是一系列具有相同特性的数据元素的有限序列,它们之间存在着一对一的相邻关系,如同项链上的珍珠,一个接一个,既独立又紧密相连。

2、链表与顺序表的区别

线性表有两种基本的存储结构:链表和顺序表。顺序表,就像是一个排列整齐的书架,每个位置都预先分配好了,书籍(数据元素)按照顺序摆放。而链表,则更像是那条珍珠项链,每颗珍珠(数据元素)都通过一根无形的线(指针)与下一颗珍珠相连,形成了一条灵活的链条。链表允许在任意位置添加或删除元素,而无需移动其他元素,这正是其独特魅力所在。

3、无头单向非循环链表

在无头单向非循环链表中,我们没有那颗象征起点的 “头珍珠” ,也没有形成一个闭环的链条。每个节点都只知道如何找到它的下一个节点(如果存在的话),但不知道整个链条的起点或终点在哪里。这种结构简洁而灵活,非常适合用于需要频繁添加或删除元素的场景。

请添加图片描述


三、无头单向非循环链表的实现

1、结构体定义

首先,我们需要定义一个结构体来表示链表中的每一个节点。这个结构体通常包含两个部分:一是存储数据元素的数据域;二是指向下一个节点的指针域。

typedef int DataType;typedef struct SListNode {DataType data;//数据域struct SListNode* next;//指针域
}SL;

2、初始化

创建一个无头单向非循环链表,首先需要初始化这个链表,即创建第一个节点,并让它指向NULL。

void Init(SL** head, DataType data)
{assert(head != NULL && *head == NULL);SL* pos = (SL*)malloc(sizeof(SL));if (pos == NULL){fprintf(stderr, "内存分配失败");exit(EXIT_FAILURE);}pos->data = data;pos->next = *head;(*head) = pos;
}

3、销毁

当链表不再需要时,我们应该及时释放它所占用的内存资源。遍历链表,逐一释放每个节点的内存,最后将头指针也置为NULL。

void Destory(SL** head)
{if (head == NULL)return;while (*head != NULL){SL* next = (*head)->next;free(*head);*head = next;}*head = NULL;
}

4、显示

为了查看链表中的元素,我们需要遍历链表,并依次打印出每个节点的数据域。

void Print(SL** head, void (*Prin) (DataType))
{assert(head != NULL && Prin != NULL);for (SL* i = *head; i != NULL; i = i->next){Prin(i->data);}printf("NULL\n");
}

5、增删查改

链表的核心操作包括增加、删除、查找和修改节点。这些操作都需要我们灵活运用指针来定位、修改或删除链表中的节点。

void PushFront(SL** head, DataType data)
{assert(head != NULL);SL* pos = (SL*)malloc(sizeof(SL));if (pos == NULL){fprintf(stderr, "内存分配失败");exit(EXIT_FAILURE);}pos->data = data;pos->next = *head;*head = pos;
}void PopFront(SL** head)
{assert(head != NULL && *head != NULL);SL* next = (*head)->next;free(*head);*head = next;
}void PushBack(SL** head, DataType data)
{Insert(head, NULL, data);
}void PopBack(SL** head)
{assert(head != NULL && *head != NULL);for (SL* i = *head; i->next != NULL; i = i->next){if (i->next->next == NULL){free(i->next);i->next = NULL;return;}}
}void Insert(SL** head, SL* x, DataType data)
{assert(head != NULL);if (*head == x){PushFront(head, data);}for (SL* i = *head; i != NULL; i = i->next){if (i->next == x){SL* pos = (SL*)malloc(sizeof(SL));if (pos == NULL){fprintf(stderr, "内存分配失败");exit(EXIT_FAILURE);}pos->data = data;pos->next = i->next;i->next = pos;return;}}assert(0);
}void Erase(SL** head, SL* x)
{assert(head != NULL && *head != NULL && x != NULL);if (*head == x){PopFront(head);}for (SL* i = *head; i != NULL; i = i->next){if (i->next == x){i->next = x->next;free(x);return;}}assert(0);
}SL* Find(SL** head, DataType data)
{assert(head != NULL && *head != NULL);for (SL* i = *head; i != NULL; i = i->next){if (i->data == data)return i;}return NULL;
}void Modify(SL** head, SL* x, DataType data)
{assert(head != NULL && x != NULL);for (SL* i = *head; i != NULL; i = i->next){if (i == x){i->data = data;return;}}assert(0);
}

四、分析无头单向非循环链表

1、存储方式

无头单向非循环链表采用动态分配内存的方式来存储节点,每个节点只保存指向下一个节点的指针。这种存储方式使得链表能够灵活地应对元素数量的变化。

2、优点

  • 无需预先分配固定大小的存储空间,能够根据需要动态地增加或减少节点。
  • 插入和删除操作的时间复杂度较低,特别是在链表中间或尾部进行操作时。

3、缺点

  • 访问链表中任意位置的元素需要从头开始遍历,因此时间复杂度较高。
  • 链表的每个节点都需要额外的指针域来存储指向下一个节点的指针,这会增加一定的内存开销。

五、总结

1、练习题

  • 分割链表
  • 环形链表的约瑟夫问题
  • 反转链表
  • 链表的中间节点
  • 合并两个有序链表
  • 移除链表元素
  • 回文链表

2、源代码

对于无头单向非循环链表的源代码我已经开源在GItee:传送门


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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

尚品汇-秒杀商品定时任务存入缓存、Redis发布订阅实现状态位(五十一)

目录: (1)秒杀业务分析 (2)搭建秒杀模块 (3)秒杀商品导入缓存 (4)redis发布与订阅实现 (1)秒杀业务分析 需求分析 所谓“秒杀”&#xff0…

百度智能云API调用

植物识别API import base64 import urllib import requestsAPI_KEY = "你的图像识别API_KEY" SECRET_KEY = "你的图像识别SECRET_KEY"def main():url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/plant?access_token=" + get_acc…

12、等保安全通用要求

数据来源:12.等保安全通用要求_哔哩哔哩_bilibili 基本要求

docker启动mysql未读取my.cnf配置文件问题

描述 在做mysql主从复制配置两台mysql时,从节点的my.cnf配置为: [mysqld] datadir /usr/local/mysql/slave1/data character-set-server utf8 lower-case-table-names 1 # 主从复制-从机配置# 从服务器唯一 ID server-id 2 # 启用中继日志 relay-l…

thop计算模型复杂度(params,flops)

thop安装 -pip install thop在线安装失败 -离线安装 github网址: pytorch-OpCounter:Count the MACs / FLOPs of your PyTorch model. - GitCode python setup.py install 测试: from options import config as c import os os.environ["CUD…

【高分系列卫星简介——高分三号卫星(GF-3)】

高分三号卫星(GF-3) 高分三号(GF-3)是我国首颗高分辨率、C频段、多极化合成孔径雷达(SAR)卫星,由中国空间技术研究院北京空间飞行器总部设计部研制,并于2016年8月10日成功发射。该卫…

vue实现扫雷代码复制即可用,vue2和vue3都可适用

效果预览 代码实现 <template><div id"app"><div class"mine-sweeper"><div class"board" v-for"row in board" :key"row-${row.index}"><divclass"cell":class"{ no-clickable…

Vue3:mitt实现组件通信

目录 一.性质 1.轻量级 2.单例 3.异步 4.事件绑定与解绑 二.作用 1.组件间通信 2.解耦 3.状态管理 4.事件的集中处理 三.使用 1.安装mitt 2.引入mitt&#xff1b;调用mitt&#xff1b;暴露mitt 3.组件1 4.组件2 四.代码 1.组件1 2.组件2 五.效果 一.性质 1…

qt-C++笔记之Q_DECLARE_METATYPE和qRegisterMetaType

qt-C笔记之Q_DECLARE_METATYPE和qRegisterMetaType code review! 文章目录 qt-C笔记之Q_DECLARE_METATYPE和qRegisterMetaType一.Q_DECLARE_METATYPE使用方法应用场景 二.为什么需要注册类型&#xff1f;三.使用 Q_DECLARE_METATYPE 处理自定义类型的简短示例3.1.自定义类型定…

ElasticSearch-2-核心语法集群高可用实战-Week2-3

ES批量操作 1.批量获取文档数据 这里多个文档是指&#xff0c;批量操作多个文档&#xff0c;搜索查询文档将在之后的章节讲解 批量获取文档数据是通过_mget的API来实现的 (1)在URL中不指定index和type 请求方式&#xff1a;GET 请求地址&#xff1a;_mget 功能说明 &#…

(C++23) expected 基础使用

文章目录 ⭐前言⭐expected&#x1f39b;️基础使用&#x1f39b;️单子操作 (Monadic operations)&#x1f39a;️and_then & or_else&#x1f39a;️transform & transform_error ⭐END&#x1f31f;跋&#x1f31f;交流方式 ⭐前言 在 C17 中&#xff0c;提出了 op…

嵌入式系统stm32cube本地安装出现的问题

stm32cube在线安装很慢&#xff0c;本地安装中出现的一个bug stm32cube_fw_f4_v1281安装成功之后&#xff0c;如果想安装stm32cube_fw_f4_v1281会提示stm32cube_fw_f4_v1280未安装。 如果先安装stm32cube_fw_f4_v1280之后&#xff0c;再安装stm32cube_fw_f4_v1281还会提示这个…

算法练习题24——leetcode3296移山所需的最小秒数(二分模拟)

【题目描述】 【代码示例&#xff08;java&#xff09;】 class Solution {// 计算让工人们将山的高度降到0所需的最少时间public long minNumberOfSeconds(int mountainHeight, int[] workerTimes) {long left 0; // 最少时间初始为0long right 0; // 最大时间初始化为0// …

java--面向对象编程(中级部分)

IDE&#xff08;集成开发环境&#xff09; java-----IDE&#xff08;集成开发环境&#xff09;-CSDN博客 包 包的三大作用 区分相同名字的类 当类很多时,可以很好的管理类[看Java API 文档] 控制访问范围 包基本语 package com.hsppedu; 说明: 1. package 关键字,表示打…

Java内存泄漏排查

内存泄漏排查 1. 堆内存快照导出2. 导入内存分析工具 1. 堆内存快照导出 获取 Java 进程 ID Windows&#xff1a;执行 jps 命令&#xff0c;或任务管理器查看&#xff0c;又或者执行 tasklist 命令。 注意&#xff1a;当有多个 Java 进程时&#xff0c;任务管理器或 tasklist |…

C++从入门到起飞之——多态 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1. 多态的概念 2. 多态的定义及实现 2.1 多态的构成条件 2.1.1 实现多态还有两个必须重要条件&…

BFS解决拓扑排序问题

文章目录 拓扑排序有向无环图&#xff08;DAG图&#xff09;AOV网&#xff08;顶点活动图&#xff09;拓扑排序实现拓扑排序 207. 课程表题目解析算法原理代码实现 LCR 113. 课程表 IILCR 114. 火星词典题目链接算法原理代码实现 拓扑排序 有向无环图&#xff08;DAG图&#x…

科研绘图系列:R语言组合多个图形

文章目录 介绍加载R包画图介绍 通过patchworkR包组合多个ggplot数据图形对象。 加载R包 library(ggplot2) library(patchwork)画图 画图theme_set(theme_bw() +theme(

全面介绍 CSS 属性值计算 —— 掌握它就了解大部分 CSS

CSS 的核心之一就在此&#xff0c;直接影响我们开发中的调试和布局&#xff01;&#xff01;&#xff01; 举个 &#x1f330;&#xff1a;页面上存在一个 h1 元素&#xff0c;不设置任何样式&#xff0c;但是当我们点开 computed 查看&#xff0c;几乎 MDN 上的 CSS 属性都存…

2206. 将数组划分成相等数对(排序/哈希)

目录 一&#xff1a;题目&#xff1a; 二&#xff1a;代码&#xff1a; 三&#xff1a;结果&#xff1a; 一&#xff1a;题目&#xff1a; 给你一个整数数组 nums &#xff0c;它包含 2 * n 个整数。 你需要将 nums 划分成 n 个数对&#xff0c;满足&#xff1a; 每个元素…