当前位置: 首页 > news >正文

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

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)

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

相关文章:

  • python:AI+ music21 构建 LSTM 模型生成爵士风格音乐
  • flutter 自定义控件RenderObjectWidget使用
  • DeepSeek 协程API 调用与 vllm推理,llamafactory本地vllm部署
  • 神经网络解决非线性二分类
  • 穿越之程序员周树人的狂人日记Part2__重构人间Beta版
  • ngx_http_add_location
  • python速通小笔记-------3.Numpy库
  • 深入理解 Spring 框架中的 AOP 技术
  • Python----计算机视觉处理(Opencv:图像轮廓特征查找:外接轮廓)
  • 华为HCIE方向那么多应该如何选择?
  • Linux的SPI子系统的原理和结构详解【SPI控制器(spi_master)、SPI总线(device-driver-match匹配机制)、SPI设备、SPI万能驱动`spidev.c`】
  • 前端性能优化方案总结
  • ARCGIS PRO SDK 创建右键菜单
  • 基于腾讯云HAI-CPU部署DeepSeek:搭建图书馆知识库,赋能智慧图书馆建设
  • 从技术架构和生态考虑,不是单纯的配置优化,还有哪些方式可以提高spark的计算性能
  • TCP 三次握手与四次挥手过程
  • Nordic Semiconductor 芯片(如 nRF52/nRF53 系列)的 VSCode 开发环境的步骤
  • 大型语言模型(LLM)推理框架的全面分析与选型指南(2025年版)
  • LLM之RAG实战(五十二)| 如何使用混合搜索优化RAG 检索
  • 鸿蒙进行视频上传,使用 request.uploadFile方法
  • 上海科创的三种品格
  • 电话费被私改成48元套餐长达数年,投诉后移动公司退补600元话费
  • 深圳宝安区一宗涉宅用地中止出让,起始总价86.27亿元
  • 法院为“外卖骑手”人身权益撑腰:依法认定实际投保人地位
  • BNEF:亚洲、中东和非洲是电力基础设施投资的最大机会所在
  • 民生访谈|宝妈宝爸、毕业生、骑手……上海如何为不同人群提供就业保障