单链表速通后续!

目录

1>>闲话

2>>头删

3>>查找

4>>在指定位置之前插入

5>>删除指定结点

6>>指定位置之后插入

7>>删除指定位置之后的结点

特别思考:

8>>销毁单链表

Slist.h

Slist.c

 test.c

9>>总结


1>>闲话

        单链表其实也不是很难对吧,学会了,认真去学了都比没学强了,就好像你看了这篇文章,获取到知识,你就比之前强了一点点,希望大家再接再厉,那么话不多说,继续后续章节。

附:单链表难?带你速通!-CSDN博客

2>>头删

        

        头删的声明也很简单,只需要传首结点地址即可。函数名front前面表示头部。

进入函数的实现,首先断言判断传进来的是不是空指针,并且判断是不是传进来了一个空结点。

接着思考,我们删除了头节点,那么头节点对应的phead也就是*pphead需要更改,直接删就不知道下一个结点地址在哪里,所以需要一个临时地址存储,那么实现:

创建一个新节点next提前存储第二个结点地址,也就是*pphead->next,然后便可以释放(free)原来结点,并让头部*pphead=第二个结点,此时头节点为原来的第二个结点。完成操作。

3>>查找

        查找的声明需要注意,返回的是一个结点的地址,那么就需要用结构体指针(SLN*)接收,这里只需要传递一级指针phead,为什么?因为不需要更改单链表里的结点,只需要查找,所以用形参就可以,x表示要查找的数据,sldatetype在前面说过,方便更改所自定义的类型名称,此时为int类型。

assert每个都是类似的,就不过多赘述啦~不懂的欢迎评论区提出来,小编都会回答的,查找需要遍历一遍单链表,只要有结果符合x,那么就返回这个结点的地址,不符合就返回空指针。

4>>在指定位置之前插入

声明有三个参数,原来的单链表头结点,指定位置(结点)pos,和插入数值x

思考:指定位置之前插入,分三个步骤:

1:新建结点

2:pos之前结点的下一个地址为新建结点

3:新建结点的地址下一个地址为pos

下面详细代码:

首先进来就要判断,这个“位置”是不是头节点,如果是的话那就是头插,直接调用头插代码就好,如果不是,那么就要新建一个结点,然后遍历单链表,注意:这里的循环判断条件和之前不一样,如果下一个地址为pos的话就退出循环,这样得到的pcur就是pos之前的结点地址,然后pcur->next等于新结点,新结点的下一个地址为pos就结束

5>>删除指定结点

声明如上,与之前类似,不多嗦啦~!

思考:与指定位置之前插入代码是否相似?少了什么?

代码如下:

相信聪明的宝宝们已经看粗来了,当pos为头结点的时候不就是进行头删吗?回答正确,奖励互三!然后还是需要找到pos之前的结点,然后另前一个结点的next为pos的next就好,注意!!所有的删除,都有free,然后把pos置为空指针就好啦!

6>>指定位置之后插入

这里代码比较简单,因为单链表往后找结点容易,往前找结点难,因此,只需要创建新节点,并且让新节点的next为pos的next,再让pos的next为新节点就好,注意:这里顺序一定不能调换,否则pos就会找不到下一个结点

7>>删除指定位置之后的结点

        

这里也比较简单只需要得知pos指向的下一个结点的下一个地址就简单了。这里不多说啦,大家看看代码。

特别思考

        在学习了时间复杂度和空间复杂度后,大家对这两有一定认识,那么请问:在指定位置之前插入和后插入时间复杂度是多少?删除指定位置和之后的时间复杂度是多少?答案写在最后啦。

8>>销毁单链表

ptail表示销毁到的结点,pcur遍历单链表,销毁(free)每一个结点,最后让*pphead也就是phead等于空指针,不然phead就会成为野指针

结束啦,感谢观看,这里附上三个文件代码,希望对大家有所帮助!

Slist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

typedef int sldatetype;

typedef struct SLnode {
	sldatetype date;
	struct SLnode* next;
}SLN;

void SLprint(SLN* phead);

void SLtailc(SLN** pphead, sldatetype x);//尾插,尾部tail+插入c

void SLtaild(SLN** pphead);//尾删,尾部tail+删除d

void SLfrontc(SLN** pphead, sldatetype x);//头插

void SLfrontd(SLN** pphead);//头删

SLN* SLfind(SLN* phead,sldatetype x);//查找

void SLinsert(SLN** pphead, SLN* pos,sldatetype x);//指定位置之前插入

void SLinsertd(SLN** pphead, SLN* pos); //删除指定结点

void SLinsertafter(SLN* pos, sldatetype x);//指定位置之后插入

void SLinsertafterd(SLN* pos); //删除指定位置后的结点

void SLruin(SLN** pphead);//销毁链表

Slist.c

#include"Slist.h"

void SLprint(SLN* phead) {
	SLN* pcur = phead;
	while (pcur) {
		printf("%d -> ", pcur->date);
		pcur = pcur->next;
	}
		printf("NULL\n");
}

SLN* buynode(sldatetype x) {
	SLN* node = (SLN*)malloc(sizeof(SLN));
	if (node == NULL) {
		perror("malloc");
		exit(1);
	}
	node->date = x;
	node->next = NULL;
	return node;
}
void SLtailc(SLN** pphead, sldatetype x) {
	assert(pphead);
	SLN* newnode = buynode(x);
	if (*pphead == NULL) {
		*pphead = newnode;
	}
	else {
		SLN* ptail = *pphead;
		while (ptail->next) {
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}
}

void SLtaild(SLN** pphead) {
	assert(pphead && *pphead);
	if ((*pphead)->next == NULL) {
		free(*pphead);
		*pphead = NULL;
	}
	else {
		SLN* pcur = *pphead;
		SLN* pend = NULL;
		while (pcur->next) {
			pend = pcur;
			pcur = pcur->next;
		}
		pend->next = NULL;
		free(pcur);
		pcur = NULL;
	}
}

void SLfrontc(SLN** pphead, sldatetype x) {
	assert(pphead);
	SLN* newnode = buynode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

void SLfrontd(SLN** pphead) {
	assert(pphead && *pphead);
	SLN* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

SLN* SLfind(SLN* phead, sldatetype x) {
	assert(phead);
	SLN* pcur = phead;
	while (pcur) {
		if (pcur->date == x) {
			return pcur;
		}
		pcur = pcur->next;
	}
	return NULL;
}

void SLinsert(SLN** pphead, SLN* pos, sldatetype x) {
	assert(pphead && pos);
	if (pos == *pphead) {
		SLfrontc(pphead, x);
	}
	else {
		SLN* newnode = buynode(x);
		SLN* pcur = *pphead;
		while (pcur->next != pos) {
			pcur = pcur->next;
		}
		pcur->next = newnode;
		newnode->next = pos;
	}
}

void SLinsertd(SLN** pphead, SLN* pos) {
	assert(pphead && *pphead && pos);
	if (pos == *pphead) {
		SLfrontd(pphead);
	}
	else {
		SLN* pcur = *pphead;
		while (pcur->next != pos) {
			pcur = pcur->next;
		}
		pcur->next = pos->next ;
		free(pos);
		pos = NULL;
	}
}

void SLinsertafter(SLN* pos, sldatetype x) {
	assert(pos);
	SLN* newnode = buynode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void SLinsertafterd(SLN* pos) {
	assert(pos && pos->next);
	SLN* posnext = pos->next;
		pos->next = posnext->next;
		free(posnext);
		posnext = NULL;
}

void SLruin(SLN** pphead) {
	assert(pphead);
	SLN* pcur = *pphead;
	SLN* ptail = *pphead;
	while (pcur) {
		pcur = pcur->next;
		free(ptail);
		ptail = pcur;
	}
	*pphead = NULL;
}

 test.c

#include"Slist.h"


void test() {
	SLN* phead = NULL;
	SLtailc(&phead, 1);
	SLprint(phead);	SLtailc(&phead, 2);
	SLprint(phead);	SLtailc(&phead, 3);
	SLprint(phead);	SLtailc(&phead, 4);
	SLprint(phead);
	SLN* find = SLfind(phead, 3);

	SLruin(&phead);
	SLprint(phead);

}
int main() {
	test();
	return 0;
}

9>>总结

        数据结构单链表篇到此结束,今天讲了单链表的各项功能实现包括:尾插、尾删、头插、头删、查找、指定位置前插/删、指定位置后插/删、销毁。希望对大家有所帮助,一起加油,一起进步!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

干货|SQL注入思路总结(非常详细)零基础入门到精通,收藏这一篇就够 了

1.SQL注入的业务场景及危害 1.1 什么是SQL注入 SQL注入是服务器端未严格校验客户端发送的数据&#xff0c;而导致服务端SQL语句被恶意修改并成功执行的行为称为SQL注入。 1.2 为什么会有SQL注入 代码对带入SQL语句的参数过滤不严格 未启用框架的安全配置&#xff0c;例如&a…

[面试] java开发面经-1

前言 目录 1.看到你的简历里说使用Redis缓存高频数据&#xff0c;说一下Redis的操作 2.说一下Redis的缓存击穿、缓存穿透、缓存雪崩 3.你的项目中使用了ThreadLocal&#xff0c;那么当有两个请求同时发出时&#xff0c;会怎么处理&#xff0c;可以同时处理两个请求吗 4.使用…

【多线程】多线程(12):多线程环境下使用哈希表

【多线程环境下使用哈希表&#xff08;重点掌握&#xff09;】 可以使用类&#xff1a;“ConcurrentHashMap” ★ConcurrentHashMap对比HashMap和Hashtable的优化点 1.优化了锁的粒度【最核心】 //Hashtable的加锁&#xff0c;就是直接给put&#xff0c;get等方法加上synch…

时间序列预测(一)——线性回归(linear regression)

目录 一、原理与目的 1、线性回归基于两个的假设&#xff1a; 2、线性回归的优缺点: 3、线性回归的主要目的是&#xff1a; 二、损失函数&#xff08;loss function&#xff09; 1、平方误差损失函数&#xff08;忽略了噪声误差&#xff09; 2、均方误差损失函数 三、随…

微服务实战——登录(普通登录、社交登录、SSO单点登录)

登录 1.1. 用户密码 PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r memberFeignService.login(vo);if(r.getCode() 0){MemberRespVo data r.getData("data", new Type…

英伟达股价分析:英伟达股价能否上涨到150美元,接下来该如何操作?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经​ 猛兽财经核心观点&#xff1a; &#xff08;1&#xff09;华尔街投行Oppenheimer已将英伟达的目标价上调到了150美元。 &#xff08;2&#xff09;产品方面的最新进展和合作伙伴关系进一步提升了英伟达的市场地位。 &…

Nacos配置管理和Nacos集群配置

目录 Nacos作为配置中心实现配置管理 统一配置管理 如何在nocas添加配置文件 在微服务拉取nacos配置中心的配置 1&#xff09;引入nacos-config依赖 2&#xff09;添加bootstrap.yaml 3&#xff09;测试&#xff0c;读取nacos配置中心中配置文件的内容 ​编辑 总结&…

ORA-65096:公用用户名或角色名无效

CREATE USER DATA_SHARING IDENTIFIED BY "Ab2"; Oracle建立用户的的时候&#xff0c;可能会出现一直提示 ORA-65096:公用用户名或角色名无效&#xff1b; 我查了一下&#xff0c;好像是 oracle 12版本及以上版本的特性&#xff0c;用户名必须加c##或者C##前缀才能创…

拆解学习【反激-PD-氮化镓】(一)

小米67W桌面快充插座&#xff1a; 反激基本拓扑&#xff1a; 商用场景下&#xff0c;这个拓扑进行了如下优化&#xff1a; 1.Q22换成了氮化镓开关管&#xff0c;当然需要适配的能驱动氮化镓的控制芯片 2.D21二极管换成了MOS管。 3.由于是AC220V输入&#xff0c;设计了整流桥…

Android Camera系列(四):TextureView+OpenGL ES+Camera

别人贪婪时我恐惧&#xff0c;别人恐惧时我贪婪 Android Camera系列&#xff08;一&#xff09;&#xff1a;SurfaceViewCamera Android Camera系列&#xff08;二&#xff09;&#xff1a;TextureViewCamera Android Camera系列&#xff08;三&#xff09;&#xff1a;GLSur…

【Nginx系列】Nginx启动失败

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

轻量服务器和云服务器ecs哪个好用一些?

轻量服务器和云服务器ecs哪个好用一些&#xff1f;轻量服务器与云服务器ECS在多方面存在显著差异&#xff0c;对于需要高性能计算和大规模数据处理的用户来说&#xff0c;ECS可能是更好的选择&#xff1b;而对于预算有限且需求较为简单的用户来说&#xff0c;轻量服务器可能更为…

Cpp::STL—list类的模拟实现(上)(13)

文章目录 前言一、结点类的实现二、迭代器类的实现迭代器类的存在意义迭代器类的模板参数构造函数运算符的重载--运算符的重载、!运算符的重载*运算符的重载->运算符的重载 总结 前言 注意本篇难度偏高&#xff0c;其主要体现在迭代器类的实现&#xff01;   什么&#xf…

QD1-P8 HTML 格式化标签(font、pre、b、strong、i、u、del、s、sub、sup)

本节学习&#xff1a;HTML 格式化标签。 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p8 ‍ 一、font 标签 用途&#xff1a;定义文本的字体大小、颜色和 face&#xff08;字体类型&#xff09;。 示例 <!DOCTYPE html> <html><head><meta cha…

JAVA-数据结构-排序

1.直接插入排序 1.原理&#xff1a;和玩扑克牌一样&#xff0c;从左边第二个牌开始&#xff0c;选中这个&#xff0c;和前面的所有牌比较&#xff0c;插在合适的位置 public static void insertsort(int[] arr){//直接插入排序for (int i 1; i < arr.length; i) {//此循环…

LOID:有效提升遮挡条件下的车道检测精度

1.论文信息 论文标题&#xff1a;LOID: Lane Occlusion Inpainting and Detection for Enhanced Autonomous Driving Systems 作者&#xff1a;Aayush Agrawal, Ashmitha Jaysi Sivakumar, Ibrahim Kaif∗, Chayan Banerjee† 作者单位&#xff1a;印度马德拉斯印度理工学院&…

Web安全 - 路径穿越(Path Traversal)

文章目录 OWASP 2023 TOP 10导图定义路径穿越的原理常见攻击目标防御措施输入验证和清理避免直接拼接用户输入最小化权限日志监控 ExampleCode漏洞代码&#xff1a;路径穿越攻击案例漏洞说明修复后的安全代码代码分析 其他不同文件系统下的路径穿越特性Windows系统类Unix系统&a…

【C++】基于红黑树封装set和map

&#x1f680;个人主页&#xff1a;小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 前言一、更高维度的泛型二、模版参数三、比较逻辑的重写四、迭代器4.1 const迭代器4.2 重载4.3 - -重载 五、完整代…

为什么很多人宁愿加钱买港版,也不愿买国行 iPhone 16

最近的 iPhone 16 市场&#xff0c;真的是倒反天罡&#xff0c;攻守异形啊。 过去&#xff0c;港版 iPhone 都是性价比的次选&#xff0c;便宜个 10% 都得考虑考虑。但今年&#xff0c;港版 iPhone 16 的价格&#xff0c;反而比国行还贵。 比如&#xff0c;闲鱼上某个卖家&am…

[红队apt]文件捆绑攻击流程

免责声明:本文用于了解攻击者攻击手法&#xff0c;切勿用于不法用途 前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文整理黑客通过文件捆绑进行攻击的流程思路 文件捆绑原理 废话只多说这一句。 1.exe和2.exe被你捆绑为3.exe。 那么你点击了3.exe就等于点…