数据结构与算法之美:单链表

        Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!

ccf542bfb390410baccf52a38dc3fdfa.gif

我的博客:<但凡.

我的专栏:《数据结构与算法之美》、《编程之路》、《题海拾贝》

欢迎点赞,关注!

目录

 

1、什么是链表

2、链表的实现 (C语言)

2.1节点的初始化

2.2节点的打印

2.3节点的插入

2.3.1头插

2.3.2尾插

2.3.3与顺序表对比

2.4节点的删除

2.4.1头删

2.4.2尾删

2.5查找

2.6指定位置之前插入数据

2.7指定位置之前插入数据

2.8删除数据

2.8.1删除指定位置之后的数据

2.8.2删除指定位置的数据

2.9销毁链表

3、C++实现部分单链表


 

1、什么是链表

        虽然链表在之前结构体那一部分介绍过,但是我们在这里再介绍一下。

        概念:链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表中的 指针链接次序实现的。

        说白了就是我们给定几块空间存储数据,这几块空间就叫节点。每个节点除了存储数据以外还存储着下一个节点的地址,这样就能用过一个节点访问下一个节点。

18cb6b9794ed49569a759c3fa27834b1.png

2、链表的实现 (C语言)

        我们还是向上次顺序表的实现一样,创建头文件和两个源文件,我们链表的增删查改和顺序表一样都用函数包装起来。同样我们的节点由结构体实现,包含两个元素:1、存放数据,2、下一个节点的地址。

2.1节点的初始化

        我们为节点开辟空间,这个操作也叫新建节点:

SListNode* BuySListNode(SLTDateType x)
{SListNode* Node = (SListNode*)malloc(sizeof(SListNode));Node->data = x;return Node;
}

        其中,x是我们想存入的数据,在初始化节点的时候我们给定节点存储的数据。

2.2节点的打印

        现在假设我们存入了几个节点的数据,我们想要打印一下:

void SListPrint(SListNode* plist)
{SListNode* pcur = plist;while (pcur->next){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL");
}

        我们先创建一个指针变量叫pcur,让他一次遍历这个链表的每一个节点,从而打印出每一个结点的数据。

2.3节点的插入

2.3.1头插

void SListPushFront(SListNode** pplist, SLTDateType x)
{SListNode* newnode = BuySListNode(x);if (*pplist == NULL){*pplist = newnode;}else{SListNode* phead = *pplist;newnode->next = phead;phead = newnode;}
}

        需要注意的是,在头插时我们要先判断这个链表是否为空,如果为空那直接让新建节点作为这个链表的头节点就好了。

2.3.2尾插

void SListPushBack(SListNode** pplist, SLTDateType x)
{SListNode* newnode=BuySListNode(x);if (*pplist == NULL){*pplist = newnode;}else{SListNode* pcur = *pplist;while (pcur->next){pcur - pcur->next;}pcur->next = newnode;}
}

2.3.3与顺序表对比

        在顺序表中,头插的时间复杂度为O(n),尾插的时间复杂度为O(1),而在链表中恰恰相反。所以说对于链表和顺序表的使用不是绝对的。(以上所说的链表是指单链表)

2.4节点的删除

2.4.1头删

void SListPopFront(SListNode** pplist)
{assert(pplist && *pplist);SListNode* pcur = (*pplist)->next;free(pplist);*pplist = pcur;
}

2.4.2尾删

void SListPopBack(SListNode** pplist)
{assert(pplist&&*pplist);SListNode* pcur = *pplist;SListNode* p = *pplist;if ((*pplist)->next == NULL){free(*pplist);*pplist = NULL;}while (pcur->next){p = pcur;pcur = pcur->next;}p->next = NULL;//先断开free(pcur);//先释放,再置空pcur = NULL;
}

        需要注意的是,只要是删除节点,我们就需要先判断一下,这个链表是否为空。这里我们选择直接断言一下。

2.5查找

SListNode* SListFind(SListNode* plist, SLTDateType x)
{SListNode* pcur = plist;while (pcur->data != x){pcur = pcur->next;}return pcur;
}

        我们这里想要查找的是存储数据为x的节点,返回类型为SListNode*

2.6指定位置之前插入数据

void SListInsertAfter(SListNode* pos, SLTDateType x)
{assert(pos);SListNode* newnode = BuySListNode(x);SListNode* pcur = pos->next;pos->next = newnode;newnode->next = pcur;
}

我们需要判断一下这个节点是否存在。

2.7指定位置之前插入数据

void SListInsert(SListNode** head,SListNode* pos, SLTDateType x)
{assert(pos);if (pos == *head){SListPopFront(pos);}else{SListNode* newnode = BuySListNode(x);SListNode* pcur = *head;while ((pcur->next) != pos){pcur = pcur->next;}pcur->next = newnode;newnode->next = pos;}
}

        这里我们先判断一下,如果pos是第一个节点,那就直接调用头插的函数。

2.8删除数据

2.8.1删除指定位置之后的数据

void SListEraseAfter(SListNode* pos)
{assert(pos&&pos->next);SListNode* del = pos->next;pos->next = del->next;free(del);//别忘了释放内存del = NULL;
}

2.8.2删除指定位置的数据

void SLTErase(SListNode** pphead, SListNode* pos)
{assert(pos);if (pos == *pphead){SListPopFront(pphead);}SListNode* pcur = *pphead;while (pcur->next != pos){pcur = pcur->next;}pcur->next = pos->next;free(pos);pos = NULL;
}

2.9销毁链表

        和顺序表一样,我们用完了应该销毁链表

void SLTDestroy(SListNode** pphead)
{assert(pphead);SListNode* pcur = *pphead;while (pcur){SListNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

3、C++实现部分单链表

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
typedef struct Node
{int a;Node* next;}Node;
Node* BuyNode(int n)
{Node* NewNode = new Node;if (NewNode == NULL){cout << "节点内存申请失败!" << endl;return NULL;}NewNode->a = n;NewNode->next = NULL;return NewNode;
}
void TouCha(Node* & ph, int x)
{Node* NewNode = BuyNode(x);NewNode->next = ph;ph = NewNode;
}
int main()
{//初始化链表Node* phead=BuyNode(5);//节点的插入TouCha(phead,5);cout << phead->a << endl;return 0;
}

        我们还没说C++,所以这部分只是作为了解,后续我会出一篇从C到C++过度的博客,所以说现在这部分内容可以不看,当然我也没写全,就写了个简单的头插。

        在C语言实现单链表时,我们对链表进行更改(插入、删除等)需要传入头节点的地址,也就是说形参是个双指针。而在C++中,我i们不用双指针,使用&重命名就可以完成这个操作(如上代码)。

        好了,今天的内容就分享到这,我们下期再见!

 

 

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

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

相关文章

样品前处理工作站自动化操作

样品前处理工作站通过集成多种技术和自动化模块&#xff0c;实现了对样品的高效、精准处理。以下是实现自动化操作的关键步骤和原理&#xff1a; 1、集成多种技术&#xff1a;工作站通常集成了液体处理、固相萃取、离心、过滤等多种技术。这些技术的结合使得工作站能够完成从样…

redis安装和使用教程【保姆级】

1.下载 通过网盘分享的文件&#xff1a;redis 链接: https://pan.baidu.com/s/1Tu1KZkf33YJFdul8s6SzqQ?pwd8888 提取码: 8888 2.启动 进入根目录&#xff0c;使用redis-server redis.windows.conf命令启行启动Redis服务&#xff0c; 如下图所示为启动成功&#xff0c;默认…

RabbitMq 基础

文章目录 一、初识 MQ1.1 同步调用&#xff1a;1.2 异步调用&#xff1a; 二、RabbitMQ三、SpringAMQP3.1 依赖和配置文件3.2 消息发送和接收&#xff1a;3.2.1 消息发送&#xff1a;3.2.2 消息接收&#xff1a; 3.3 WorkQueues 模型&#xff1a;3.4 交换机类型&#xff1a;3.4…

建筑行业数据分析如何做?

导读&#xff1a;在谈数字化转型之前&#xff0c;先来谈谈数据的价值。数字化转型的基础是数据&#xff0c;是数字化的基本的生产资料&#xff0c;数据的质量直接决定了数字化的能力、所能达到的深度和广度。目前做的数据可视化项目总感觉只是数据展现而已&#xff0c;而不达不…

电脑投屏到电脑:Windows,macOS及Linux系统可以相互投屏!

本篇其实是电脑远程投屏到另一台电脑的操作介绍。本篇文章的方法可用于Windows&#xff0c;macOS及Linux系统的相互投屏。 为了避免介绍过程中出现“这台电脑”投屏到“那台电脑”的混乱表述&#xff0c;假定当前屏幕投出端是Windows系统电脑&#xff0c;屏幕接收端是Linux系统…

随时随地掌控数据:如何使用手机APP远程访问飞牛云NAS

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

2024-12-04OpenCV视频处理基础

OpenCV视频处理基础 OpenCV的视频教学&#xff1a;https://www.bilibili.com/video/BV14P411D7MH 1-OpenCV视频捕获 在 OpenCV 中&#xff0c;cv2.VideoCapture() 是一个用于捕获视频流的类。它可以用来从摄像头捕获实时视频&#xff0c;或者从视频文件中读取帧。以下是如何使用…

ubuntu安装navicat,并使用navicat连接mysql服务

1.安装宝塔&#xff1a; 登录宝塔官网&#xff1a;https://www.bt.cn/new/download.html 使用对应命令安装宝塔&#xff0c;然后搭建mysql环境。 2.安装navicat 有需要教程的私我&#xff0c;我再更新整理出来 &#xff01;&#xff01;&#xff01; 有需要教程的私我&#xf…

深度学习:MindSpore自动并行

随着模型规模的逐渐增大&#xff0c;需要的算力逐渐增强&#xff0c;但是算力需求增长速度远高于芯片算力增长速度。现在唯一的解决方案只有通过超大规模集群训练大模型。 大集群训练大模型的挑战 内存墙 200B参数量的模型&#xff0c;参数内存占用745GB内存&#xff0c;训练…

Qt Designer Ui设计 功能增加

效果展示 输入密码&#xff0c;密码错误&#xff0c;弹出提示 密码正确&#xff0c;弹出提示并且关闭原窗口 代码&#xff08;只提供重要关键主代码&#xff09;lxh_log.py代码&#xff1a; import sysfrom PySide6.QtWidgets import QApplication, QWidget, QPushButtonfrom …

版本控制器git

版本控制git 什么是版本控制&#xff1f; 版本控制是一种跟踪管理文件变化的技术&#xff0c;特别是软件源码的修改、更新、和历史记录。当程序员想要进行用到之前版本的代码可以进行查看、协作、并编辑文件。 举个栗子 当一位初入职场的萌新程序员在进行执行产品经理的需求时…

jetbrain 插件开发初体验

idea插件开发初体验 背景 标准化的git commit Message很重要&#xff0c;一直以来我用的都是commit-template-idea-plugin&#xff0c;他提供的模板遵循了conventionalcommits规范 <type>(<scope>): <subject> <BLANK LINE> <body> <BLANK…

解决raw.githubusercontent.com无法访问的问题

显示报错&#xff1a;ConnectionError: Couldn’t reach https://raw.githubusercontent.com/huggingfac 无法访问 在https://www.ipaddress.com 或者ip138.com网站中的查询框中输入&#xff1a;raw.githubusercontent.com 回车就能有下图中的网页&#xff0c;在里面找到相应的…

高效职场人

文章目录 1.时间效能 ABCD2.高效员工的习惯之 自我掌控的秘诀3.学会做主4.学会互赢5.学会沟通、学会聆听6.学会可持续发展&#xff1a;四个方面更新自我(1)更新身体(2)更新精神(3)更新智力(4)更新人际情感 1.时间效能 ABCD 时间四象限&#xff1a; A类任务&#xff1a;重要且紧…

数据结构 (33)选择类排序

前言 数据结构中的选择类排序主要包括简单选择排序&#xff08;也称为选择排序&#xff09;和堆排序。 一、简单选择排序 基本思想&#xff1a;简单选择排序是一种直观易懂的排序算法。它的工作原理是&#xff0c;在未排序序列中找到最小&#xff08;或最大&#xff09;元素&am…

Kubernetes架构原则和对象设计(二)

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes常见问题解答 本文从云计算架构发展入手&#xff0c;详细分析了kubernetes的生态系统、设计理念、分层架构、API设计…

自建服务器,数据安全有保障

在远程桌面工具的选择上&#xff0c;向日葵和TeamViewer功能强大&#xff0c;但都存在收费昂贵、依赖第三方服务器、数据隐私难以完全掌控等问题。相比之下&#xff0c;RustDesk 凭借开源免费、自建服务的特性脱颖而出&#xff01;用户可以在自己的服务器上部署RustDesk服务端&…

发布Apache2.4** 局域网无法访问

1。 防火墙关闭 或者 设置入站规则 2&#xff0c;查看httpd.conf 文件 设置配置 原 Listen 80 修改成 Listen 192.168.31.127:90 3.确保 本地IP 是否正确

Flutter解压文件并解析数据

Flutter解压文件并解析数据 前言 在 Flutter 开发中&#xff0c;我们经常需要处理文件的读取和解压。 这在处理应用数据更新、安装包、存档文件等场景中尤为常见。 本文将介绍如何在Flutter中使用archive插件来解压文件并解析数据。 准备 在开始之前&#xff0c;我们需要…

HiveSQL题——炸裂函数(explodeposexplode)

目录 一、炸裂函数的知识点 1.1?炸裂函数 ?explode? posexplode 1.2 lateral view 侧写视图 二、实际案例 2.1 每个学生及其成绩 0 问题描述 1 数据准备 2 数据分析 3 小结 2.2?日期交叉问题 0 问题描述 1 数据准备 2 数据分析 3 小结 2.3?用户消费金额 …