单链表的查找和插入,删除操作

news/2025/3/26 3:42:18/

1.单链表的查找

snode* slistfind(snode* stlheap, stltype x)
{while (stlheap){if (stlheap->data == x){return stlheap;}stlheap = stlheap->next;}return NULL;
}

2.单链表的插入操作

2.1在指定位置之前插入节点

void slistinsert(snode** stlheap, snode* pos, stltype x)
{assert(*stlheap && pos);//确保他俩都不为空if (*stlheap == pos){//相当于头插stlpushfront(stlheap, x);return;}snode* temp = (snode*)malloc(sizeof(snode));temp->data = x;temp->next = NULL;//开一个节点snode* temp1 = *stlheap;while (temp1->next != pos){temp1 = temp1->next;}//此时两个节点相邻temp1->next = temp;temp->next = pos;
}

说几个注意点,传的是2级指针,所以在需要改变头指针位置的时候,我们就解引用就行

在不需要改变头指针的值的时候,我们就用一个一级指针来代替它的作用,这样的结果是防止头指针位置变了,导致链表错位。

其次,在插入过程中,我们先判断,传入的指针是否为空。如果不为空就继续接下来的插入操作。

这里你可能好奇,pos指针是怎么来的,难道每次我都要循环遍历吗,其实不然,在我们前面写的查找操作中,就可以返回一个指针,可以将这个指针用到这里。

然后,对于插入的大部分操作,我们都是找到两个节点,然后改变他们两个加temp指针的值。

但如果没有3个节点,比如要在第一个节点之前插入呢?

此时问题就变成了头插的问题,而且这种问题是和我们正常插入操作矛盾的,因为他们需要的节点数量是不同的,因此,我们需要进行判断,来解决这类问题。

2.2在指定位置之后插入节点

void slistinsertafter(snode* pos, stltype x)
{assert(pos);snode* temp = (snode*)malloc(sizeof(snode));temp->data = x;temp->next = NULL;//开一个节点temp->next = pos->next;pos->next = temp;}

这里由于链表也是一种顺序表,而且我们是在指定位置之后插入数据,因此我们不需要头指针。

同时,这里我们只需要两个节点,因此也不需要考虑头插和尾插的关系。因此代码就变得很简单了。

2.3两种方式的时间复杂度分析

对于第一种方式,存在一个while循环,因此最坏情况下时间复杂度为O(n)

对于第二种方式,不存在循环等,时间复杂度为O(1)

3.单链表的删除操作

3.1删除指定位置的节点

void slisterase(snode** stlheap, snode* pos)
{assert(*stlheap && pos);if (pos == *stlheap){slistpopfront(stlheap);}else{snode* temp = *stlheap;while (temp->next != pos){temp = temp->next;}temp->next = pos->next;free(pos);pos = NULL;}
}

还是传2级指针,因为可能会删掉头节点,同样的这题我们还是要分类讨论,不再重复叙述原因了。

3.2删除指定位置之后的节点

void slisteraseafter(snode* pos)
{assert(pos);if (pos->next == NULL)return;snode* temp = pos->next;pos->next = pos->next->next;free(temp);temp = NULL;
}

这里同样也得分类讨论。

3.3两种方法的时间复杂度分析

第一种时间复杂度为O(n)

第二种时间复杂度为O(1)

4.链表的销毁

void slistdestory(snode** stlheap)
{snode* temp1 = *stlheap;while (temp1){snode* temp2 = temp1->next;free(temp1);temp1 = temp2;}*stlheap = NULL;
}

在这个过程中考虑,释放节点后,对应的next也会消失

因此顺序很重要,同时也考虑到了链表为空的情况

5.单链表的本质

其实单链表的本质就是一种顺序表,而且单链表只能从前向后遍历,不能从后向前遍历。

这也就导致了,删除或插入指定位置或当前位置之前的时间复杂度为O(n)

因为涉及到了一个循环遍历的问题。

删除或插入指定位置之后的操作时间复杂度为O(1)

因为不涉及到循环问题,直接从给的位置开始就可以了。


http://www.ppmy.cn/news/1583122.html

相关文章

Linux:基础IO---文件描述符

文章目录 1. 前言1.1 C语言文件知识回顾 2. 文件2.1 文件基础知识 3. 被打开的文件3.1 以C语言为主,先回忆一下C文件接口3.2 过渡到系统,认识文件系统调用3.3 访问文件的本质3.4 重定向&&缓冲区 序:在深入了解了进程的内容后&#xf…

游戏引擎学习第172天

总结今天的计划 这次的项目我们没有使用任何游戏引擎或者第三方库,而是完全自己动手编写。这种方式可能没有经济效益,但我认为每个人都应该有一次亲身经历,了解开发一款游戏时所涉及的所有内容。这样能让开发者更加灵活,能够做很…

数学建模:MATLAB卷积神经网络

一、简述 卷积神经网络是一种处理具有网格结构数据的深度学习模型,由输入层、卷积层、池化层、全连接层、输出层组成。 输出层:将图像转换为其对应的由像素值构成的二维矩阵,并存储二维矩阵 卷积层:提取图像的底层特征&#xf…

智慧医院、养老人员高精度定位解决方案

随着医院就医人数的不断增加,人员管理方面出现了诸多漏洞,表现为患者私自走出病房甚至医院;新生婴儿的有效管理,患者遇到突发病情,得不到及时救助,医疗设备看管措施不够严密,出现丢失等。 品铂科技高精度定…

Windows下rust的安装

前言 Python在编译某些包的时候需要用到rust,一怒之下就打算直接将rust安装上。我采用的平台是Windows。 一、登录rust官网 https://rustup.rs/ 二、安装 下载完毕后,直接运行,呈现如下画面: 回车,继续即可。(打算简…

【AndroidRTC-11】如何理解webrtc的Source、TrackSink

Android-RTC系列软重启,改变以往细读源代码的方式 改为 带上实际问题分析代码。增加实用性,方便形成肌肉记忆。同时不分种类、不分难易程度,在线征集问题切入点。 问题1:如何理解VideoSource、VideoTrack&VideoSink三者的关系…

4(四) Jmeter自动化报表html生成

从JMeter 3.0开始已支持自动生成动态报告,我们可以更容易根据生成的报告来完成我们的性能测试报告。 如何生成html测试报告 如果未生成结果文件(.jtl),可运行如下命令生成报告: jmeter -n -t test.jmx -l result.jtl -e -o /tmp/ResultReport…

解决chrome无法通过公网访问内网(或者127.0.0.1)

Chrome 更新至 94 版本后,为了保护用户免受针对专用网络(也就是内网)上的路由器和其他设备的跨站点请求伪造 (CSRF) 攻击,限制网站向专用网络上服务器发送请求的能力,该限制当前(Chrome94)中可以用配置开关临时解除&am…