数据结构对链表的初步认识(一)

已经两天没有更新了,今天就写一篇数据结构的链表吧,巩固自己也传授知识,不知道各位是否感兴趣看看这一篇有关联表的文章。

目录

链表的概念与结构

 单向链表的实现

链表各个功能函数


首先我在一周前发布了一篇有关顺序表的文章,其中我们通过简单的介绍和代码实践,已经基本了解顺序表了,那么即使我们把顺序表弄成动态的顺序表,但其实我们运用顺序表还是有以下问题:

1. 如果空间不够,我们进行增容。但增容回付出一定的性能消耗,其次可能存在一定的空间浪费,因为我们每次增容都是2倍的增容我们可能并用不完这两倍的空间。

2.头部和中部左右两部分的插入效率太低,因为我饿们需要将数据一个一个的往后移,所以效率不高。

 

那么我们要怎么解决这个问题呢?

1.空间上  ,按照需求给空间,比如我要101个空间就给我101个空间而不是两倍。

2.不要求物理空间上的连续,这样在头部和中部时我们就不需要挪动数据,那么这种解决方法就是用链表实现。

 

OK,我们下面就展开展开链表的知识了。


链表的概念与结构

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

其逻辑结构(这里说的逻辑结构是我们想象出来便于理解的结构):

上方逻辑结构可以是n个数据和指针,这样我们就完成了,非物理空间上的连续的表。

链表有许多结构我们今天就讲一种简单的结构——————单向链表。


 单向链表的实现
 

我们继续创建一个结构体,里面是数据和指针。

typedef int SLTDataType;
struct SListNode
{SLTDataType data;struct SListNode* next;
};
typedef struct SListNode SLTNode;

代码中将结构体命名为SLTNode是为了方便写代码。 

typedef int SLTDataType  为了易于改变数据类型时,只需将int 改成其他类型即可改变 ,整个链表的数据类型。

struct SListNode* next   这里面储存一个结构体指针用来链接下一个结构体。

既然结构体已经完成了,那么我们现在就简单用函数链接一个链表了。


链表各个功能函数

 

链表必须要找一个头,即链表的首个结构体,那么我们就将这个头命名为 plist,传给其他函数完成其功能。

现在我们就实现第一个函数,开辟空间的函数。

SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));newnode->data = x;newnode->next = NULL;return newnode;
}

这个函数主要用于链表的增加,在各个部位进行插入数据都需要这个函数开辟空间。 


头插函数

如何头插呢?这是我们需要思考的。

void SListPushFront(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;
}

链表头插即开辟一块新的空间,将这块空间作为头(*pphead = newnode;),而这块空间的next则储存着原来的头结构体(newnode->next = *pphead;) 。

注意:这里要改变pist本身则我们就要使用指针进行传址,改变其地址。


 头删函数

这个函数也相较简单,我们也是将第一个节点删除,然后将第二个节点设为头节点,而第二个节点就是原来头节点里储存的 next了,我们必须先储存第二节点的地址然后再进行销毁。

void SListPopFront(SLTNode** pphead)
{SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}


尾插函数

尾插函数,我们只需先创建一个新空间newnode,然后将原来的尾的结构体中的 next 改为现在newnode 即可。但需要注意当链表还一个节点都没有的时候,原来是没有尾的,这又是一种情况,我们只需将*pphead变为newnode,即可。由此得出下面代码。

void SListPushBack(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);if (*pphead == NULL){*pphead = newnode;}else{// 找尾节点的指针SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}// 尾节点,链接新节点tail->next = newnode;}
}

 


 尾删函数

尾删时我们需要考虑三种情况 

 1、空
 2、一个节点
 3、一个以上的节点

空的时候我们不需要任何操作,直接return即可。

一个节点时我们需要用free函数进行销毁空间,然后将该*phead 赋一个NULL。

一个节点i以上我们要考虑的又有些不同,因为当我们将尾节点删除时我们还需将倒数第二个节点赋为NULL不然程序可能会崩掉。我们知道找最后一个尾节点很容易但是我们要找倒数第二个节点很难 ,这里我们就需要借助第三指针变量,一前一慢进行往后遍历,最后即可得到这两个节点了。

void SListPopBack(SLTNode** pphead)
{// 1、空// 2、一个节点// 3、一个以上的节点if (*pphead == NULL){return;}else if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* prev = NULL;SLTNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}

 


打印函数

以NULL为链表结束标志,即打印结束。 

void SListPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur != NULL){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}

 下面给大家展示一下这些函数:

void Test()
{SLTNode* plist = NULL;SListPushFront(&plist, 8);SListPushFront(&plist, 88);SListPushBack(&plist, 29);// 88 8 29SListPrint(plist);SListPopBack(&plist);SListPushFront(&plist, 5);SListPushBack(&plist, 89);// 5 88 8 89SListPrint(plist);SListPopFront(&plist);SListPrint(plist);//88 8 89}int main()
{Test();return 0;
}


 文章到这就结束了。

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

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

相关文章

漏洞原理 | CORS跨域学习篇

本文由掌控安全学院 - 帆先生 投稿 0x01:原理 1、 什么是CORS 全称跨域资源共享,用来绕过SOP(同源策略)来实现跨域访问的一种技术。 CORS漏洞利用CORS技术窃取用户敏感信息 2、 同源策略简介 同源策略是浏览器最核心也是最基本的安全功能&#xff0…

Netty中的内置通信模式、Bootstrap和ChannelInitializer

内置通信传输模式 NIO:io.netty.channel.socket.nio 使用java.nio.channels包作为基础–基于选择器的方式Epoll:io.netty.channel.epoll由JNI驱动的epoll()和非阻塞IO.这个传输支持只有在Linux上可用的多种特性,如果SO_REUSEPORT,比NIO传输更快&#xf…

layui表格中使用cascader后导致表格滚动条消失

修改前,受影响页面 修改后最终想要的效果 修改方法

TIM编码器接口(编码器测速)

定时器编码器接口自动计次--------->对应手册14.3.12编码器接口模式 应用场景: 电机控制PWM驱动电机,编码器测电机速度,PID算法闭环控制 ------------------------------------------------------------------------------------------…

Java IO详解

一、流的概念与作用 流(Stream): 在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据传输过程。人们根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。你既可以从流中读取数据,也可以往流中写数据。流的…

计算机毕业设计SSM基于的高校学习资源共享系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: vue mybatis Maven mysql5.7或8.0等等组成,B…

Camtasia2023破解版下载

Camtasia2023破解版是一款简单好用的屏幕录像软件,它结屏幕录制和录制视频编辑等功能于一身,不管是用来创建视频教程还是相关教学视频或者操作演示等都是不二的选择,软件支持录制全屏或者部分区域进行选择录制,可录制网络摄像头、…

DTAN: Diffusion-based Text Attention Network for medical imagesegmentation

DTAN:基于扩散的医学图像分割文本关注网络 摘要 在当今时代,扩散模型已经成为医学图像分割领域的一股开创性力量。在此背景下,我们引入了弥散文本注意网络(Diffusion text - attention Network, DTAN),这是一个开创性的分割框架&#xff0c…

第五节笔记:LMDeploy 大模型量化部署实践

大模型部署背景 参数用FP16半精度也就是2字节,7B的模型就大约占14G 2.LMDeploy简介 量化降低显存需求量,提高推理速度 大语言模型推理是典型的访问密集型,因为是decoder only的架构,需要token by token的生成,因…

【数据结构排序算法篇】----基数排序【实战演练】

作为一名对技术充满热情的学习者,我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代,我远非专家,而是一位不断追求进步的旅行者。通过这篇博客,我想分享我在某个领域的学习经验,与大家共同探讨、共…

鸿蒙语言ArkTS(更好的生产力与性能)

ArkTS是鸿蒙生态的应用开发语言 ArkTS提供了声明式UI范式、状态管理支持等相应的能力,让开发者可以以更简洁、更自然的方式开发应用。 同时,它在保持TypeScript(简称TS)基本语法风格的基础上,进一步通过规范强化静态检…

Quantitative Analysis: PIM Chip Demands for LLAMA-7B inference

1 Architecture 如果将LLAMA-7B模型参数量化为4bit,则存储模型参数需要3.3GB。那么,至少PIM chip 的存储至少要4GB。 AiM单个bank为32MB,单个die 512MB,至少需要8个die的芯片。8个die集成在一个芯片上。 提供816bank级别的访存带…