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

devtools/2025/3/25 23:55:48/

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/devtools/171193.html

相关文章

常见中间件漏洞(Apache)

CVE-2021-41773 该漏洞是由于Apache HTTP Server 2.4.49版本存在目录穿越漏洞,在路径穿越目录 <Directory/>Require all granted</Directory>允许被访问的的情况下&#xff08;默认开启&#xff09;&#xff0c;攻击者可利用该路径穿越漏洞读取到Web目录之外的其他…

【Linux】Reactor模式

文章目录 &#x1f449;Reactor 模式&#x1f448;什么是 Reactor 模式Reactor 模式的组件Reactor 模式的工作流程 &#x1f449;使用 Reactor 模式设计 TcpServer&#x1f448;socket 的封装日志模块Epoll 模型的封装TcpServer 的设计协议定制服务端的编写客户端的编写将业务替…

夯实 kafka 系列|第二章:kafka 常用参数配置

文章目录 1.前言2.常用参数2.1 broker 参数2.1.1 log.dirs2.1.2 ZooKeeper 集群2.1.3 数据留存&#xff08;全局级别&#xff09; 2.2 topic 参数2.2.1 数据留存&#xff08;topic级别&#xff09;2.2.2 auto.create.topics.enable 2.3 jvm 参数2.4 动态参数2.4.1 概述2.4.2 常…

卡特兰数在数据结构上面的运用

原理 Catalan数是一个数列&#xff0c;其第n项表示n个不同结点可以构成的二叉排序树的数量。Catalan数的第n项公式为&#xff1a; &#xfffc; 其中&#xff0c;&#xfffc;是组合数&#xff0c;表示从2n个元素中选择n个元素的组合数。 Catalan数的原理可以通过以下方式理解&…

【数据库】sql错题详解

1. 执行子查询 SELECT 供应商号 FROM 订购单 WHERE 职工号 IN (E1, E3) GROUP BY 供应商号 HAVING COUNT(DISTINCT 职工号) 2筛选职工号为 E1 或 E3 的记录&#xff1a; 依据 WHERE 职工号 IN (E1, E3) 这个条件&#xff0c;从 订购单 表中把职工号为 E1 或者 E3 的记录筛选出…

零、ubuntu20.04 安装 anaconda

1.anaconda下载 地址&#xff1a;Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 选择&#xff1a;Anaconda3-2023.07-2-Linux-x86_64.sh 2.anaconda安装 选择下载目录&#xff0c;选在在终端中打开&#xff0c;然后在终端输入安装命…

C# SerialPort 使用详解

总目录 前言 在工业控制、物联网、嵌入式开发等领域&#xff0c;串口通信&#xff08;Serial Port Communication&#xff09;是连接串行设备&#xff08;如条码扫描器、GPS接收器等&#xff09;与计算机的重要手段。C# 提供了内置的 SerialPort 类&#xff0c;简化了串口开发…

ue5蓝图项目转换为c++项目 遇到的问题

蓝图项目转c项目 工具/新建C类&#xff0c;随便新建一个c类&#xff0c;即可从蓝图项目转换为c项目 如果转换正常&#xff0c;UE5会要求重新编译程序&#xff0c;并在编译完后自动打开VS 转换前要备份 转换失败的原因 电脑上必须安装了.Net6.0&#xff0c;其他版本高了低了…