链表的基础

 

目录

顺序表

链表

需要注意的 

链表的优势 

 单链表的实现

1.单链表的准备

2.单链表的结构体的创建

 3.单链表的准备

 4.前插

5.后插

 6.后删

7.前删

8.任意位置前插

9.任意位置后插

 10.删除

11.修改

12.打印

13.释放链表


 总说链表难,但我感觉只要认真听讲,再加上自己敲敲代码,也不是很难,毕竟后面还有更难的算法  哈哈

顺序表

想要了解什么是链表,我们要先知道什么是顺序表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结 构,常见的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物 理上存储时,通常以数组和链式结构的形式存储

 这一点在通讯录的实现给出了充足的运用,然后向更深的探索,也就慢慢产生了链表

链表

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

这就好比火车一样,每个车间都装着东西,然而车间与车间之间并不是向顺序表一样直接加加向后,而是每个车间是通过中间车钩连接起来的,

 在数据结构上的链表也是同样道理,在一个结构体内,有一部分装着必要的信息,而另一部分又有指针,该指针存放着下一个结构体的地址,使得两个结构体如果火车一样连接在一起;

文字表示固然不清楚,我们展示图形:

此处只展示单链表,单链表会的话,双链表也是同样道理,可以自己实现 

需要注意的 

我们的链表最后一个节点的指针部分,必须存放的是NULL这里我们需要自己写代码让其为NULL要不然没有这一步,我们不知道结束的判断是什么 

链表的优势 

这里是摘自别人的博客 

 链表基础知识详解(非常详细简单易懂)-CSDN博客

人家写的比我写的详细多了,还讲解了双链表,值得学习 

 

   链表是通过节点把离散的数据链接成一个表,通过对节点的插入和删除操作从而实现 对数据的存取。而数组是通过开辟一段连续的内存来存储数据,这是数组和链表最大的区 别。数组的每个成员对应链表的节点,成员和节点的数据类型可以是标准的 C 类型或者是 用户自定义的结构体。数组有起始地址和结束地址,而链表是一个圈,没有头和尾之分, 但是为了方便节点的插入和删除操作会人为的规定一个根节点。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_61672347/article/details/125701955

 单链表的实现

1.单链表的准备

我们先写出需要用到的头文件 

#include <stdio.h>
#include <string.h>
#include<malloc.h>
#include<stdlib.h>
#include<assert.h>
#include<errno.h>

typedef int SLDataType;

这里的重命名是为了方便以后修改

2.单链表的结构体的创建

一部分存放需要存的信息,一部分为指针存放下一个结构体的地址

typedef int SLDataType;

typedef struct SLList
{
    SLDataType x;
    struct SLList* next;
}SL;

 3.单链表的准备

int main()
{
	SL* SLList=NULL;
	return 0;
}

 4.前插

前插需要考虑的就是如果单链表本来就没有节点 

大致图:

需要注意的是我们传的是指针的地址,我们需要用二级指针接收,才可以改变一级指针指向的内容

	SLPushFront(&SLList, 5);

    void SLPushFront(SL** pphead, SLDataType x)
{
	assert(pphead);
	SL* newcode = (SL*)malloc(sizeof(SL));
	if (newcode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newcode->next = *pphead;
	newcode->x = x;
	*pphead = newcode;
}

5.后插

 后插跟前插同样的道理

 同样需要考虑的是没有节点的问题与只有一个节点

void SLPushback(SL** pphead,SLDataType x)
{
	assert(pphead);
	SL* newcode = (SL*)malloc(sizeof(SL));
	if (*pphead == NULL)
	{
		*pphead = newcode;
		(*pphead)->x = x;
		(*pphead)->next = NULL;
		return;
	}
	SL* tail = *pphead;
	while (tail->next != NULL)
	{
		tail = tail->next;
	}
	tail->next = newcode;
	tail = tail->next;
	tail->x = x;
	tail->next = NULL;
}

 6.后删

 

后删同样需要考虑没有节点,没有节点当然删不了啊,还有只有一个节点,我们需要直接将这个节点直接释放,然后等于NULL

void SLPopBack(SL** pphead)
{
	assert(pphead);
	assert(*pphead);
	SL* tail = *pphead;
	//一个也没有
	assert(*pphead);
	//一个节点
	if ((*pphead)->next==NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	//多个节点
	while (tail->next->next != NULL)
	{
		tail = tail->next;
	}
	free(tail->next);
	tail->next = NULL;
}

7.前删

void SLPopFront(SL** pphead)
{
	assert(pphead);
	assert(*pphead);
	SL* tail = *pphead;
	*pphead = (*pphead)->next;
	free(tail);//tail是SL* tail=&SLList;
}

8.任意位置前插

 我们需要先找到该位置,然后在与前面前插后插同样方法进行插入

	SL* pos = SLFind(SLList,2);
	SLInsert(&SLList,pos,20);//前插
	SLPrint(SLList);
SL* SLFind(SL* pphead, SLDataType x)
{
	assert(pphead);
	SL* tail = pphead;
	while (tail->x != x)
	{
		tail = tail->next;
	}
	return tail;
}

void SLInsert(SL** pphead, SL* pos, SLDataType x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	SL* newcode = (SL*)malloc(sizeof(SL));
	if (newcode == NULL)
	{
		perror("SLInsert fail");
	}
	while (tail->next != pos)
	{
		tail = tail->next;
	}
	newcode->next = tail->next;
	newcode->x = x;
	tail->next = newcode;
}

9.任意位置后插

	SL* pos = SLFind(SLList,2);
    SLInsertBack(&SLList, pos, 30);//后插
	SLPrint(SLList);
void SLInsertBack(SL** pphead, SL* pos, SLDataType x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	SL* newcode = (SL*)malloc(sizeof(SL));
	if (newcode == NULL)
	{
		perror("SLInsertBack fail");
	}
	while (tail != pos)
	{
		tail = tail->next;
	}
	newcode->next = tail->next;
	newcode->x = x;
	tail->next = newcode;
}

 10.删除

	SL* pos = SLFind(SLList,2);

	SLErase(&SLList, pos);
	SLPrint(SLList);
void SLErase(SL** pphead, SL* pos)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	if (pos == *pphead)
	{
		SLPopFront(pphead);
		return;
	}
	while (tail->next != pos)
	{
		tail = tail->next;
	}
	tail->next = pos->next;
	free(pos);
}

11.修改

	pos= SLFind(SLList, 3);
	SLModify(&SLList, pos, 50);
	SLPrint(SLList);
void SLModify(SL** pphead, SL* pos, SLDataType x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	while (tail != pos)
	{
		tail = tail->next;
	}
	tail->x = x;
}

12.打印

void SLPrint(SL* pphead)
{
	SL* tail = pphead;
	while (tail != NULL)
	{
		printf("%d->", tail->x);
		tail = tail->next;
	}
	printf("NULL\n");
}

13.释放链表

void SLList_free(SL** pphead)
{
	//定义一个指针变量保存头结点的地址
	SL* pb = *pphead;
	while (*pphead != NULL)
	{
		//先保存p_head指向的结点的地址
		pb = *pphead;
		//p_head保存下一个结点地址
		*pphead = (*pphead)->next;
		free(pb);
		pb = NULL;
	}
}

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

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

相关文章

C语言:深入补码计算原理

C语言&#xff1a;深入补码计算原理 有符号整数存储原码、反码、补码转换规则数据与内存的关系 补码原理 有符号整数存储 原码、反码、补码 有符号整数的2进制表示方法有三种&#xff0c;即原码、反码和补码 三种表示方法均有符号位和数值位两部分&#xff0c;符号位用0表示“…

算法第二十六天-删除有序数组中的重复项Ⅱ

删除有序数组中的重复项 题目要求 解题思路 题目要求中提到原地修改&#xff0c;那么肯定需要一个指针指向当前即将放置元素的位置&#xff0c;需要另外一个指针向后遍历所有元素&#xff0c;所以[双指针]解法呼之欲出。 慢指针slow&#xff1a;指向当前元素放置的位置&…

蓝桥杯第一天

这题就是典型的位数贡献大于数量贡献&#xff0c; 1花的火柴更少&#xff0c;所以尽量用完10个1&#xff0c;然后其实就是简单的背包问题尽量拿最多的物品&#xff08;数字&#xff09;&#xff0c;限重为300&#xff0c;各物品&#xff08;数字&#xff09;的重量即为所需火柴…

波动数列 刷题笔记

思路分析 dp 找出状态转移方程 设d为a或者-b 代码 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N1010,MOD100000007; int get_mod(int a,int b){ return (a%bb)%b; …

深入解读 Elasticsearch 磁盘水位设置

本文将带你通过查看 Elasticsearch 源码来了解磁盘使用阈值在达到每个阶段的处理情况。 跳转文章末尾获取答案 环境 本文使用 Macos 系统测试&#xff0c;512M 的磁盘&#xff0c;目前剩余空间还有 60G 左右&#xff0c;所以按照 Elasticsearch 的设定&#xff0c;ES 中分片应…

全国保护性耕作/常规耕作农田分类数据集

基于Sentinel-2遥感产品&#xff0c;使用来自文献调研和目视解译产生的保护性/常规耕作样本点&#xff0c;通过交叉验证方法训练随机森林分类器&#xff0c;生成了2016-2020年全国保护性耕作/常规耕作农田分类数据集。分类代码&#xff1a;0值代表非农田&#xff0c;1值表示第一…

laravel-admin 头部添加操作

新建html 样式及js namespace App\Admin\Extensions\Nav;class Links {public function __toString(){return <<<HTML<li><a href"" οnclick"js_method();return false;"><i class"fa fa-floppy-o"></i><s…

方法的使用

1.什么是方法(method) 在java中方法就是一个代码片段.。几乎相当于c语言的函数。 2.方法定义 方法跟函数是几乎一样的。所以语法是大差不差的。就多了一点东西。之前我们在c语言里已经很详细讲过了函数。这里就简便的讲一下。 相比c语言函数多了个修饰符 。 现在看下其注意…

深入理解JavaScript内存泄漏:原因与解决方法

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Visual C++ 2010学习版安装教程

1. 创建项目 点击 “创建新项目”&#xff0c;创建一个项目。 2. 创建 helloworld.c ⽂件 3. 在弹出的编辑框中&#xff0c;选中 “C文件(.cpp)”&#xff0c;将 下方 “源.cpp” 手动改为要新创建的文件名。 如&#xff1a;helloWorld.c 。注意&#xff0c;默认 cpp 后缀名&am…

记录西门子:IO隔离SCL编程

在PLC变量中创建IO输入输出 在PLC类型中创建输入和输出&#xff0c;并将PLC变量的输入输出名称复制过来 创建一个FC块或者FB块 创建一个DB块 MAIN主程序中&#xff1a;

文件包含漏洞初识

一、基础知识介绍 在web后台开发的时候&#xff0c;我们会使用PHP&#xff0c;Java这种代码&#xff0c;而在使用的过程中&#xff0c;我们经常会使用包含函数&#xff08;也就是调用&#xff09;&#xff0c;而很多时候&#xff0c;前端用户在选择浏览时会调用包含的文件这无…

使用CSS制作动态的环形图/饼图

使用纯 CSS Animation conic-gradient 实现一个环形图。 饼图的实现思路和环形图一样&#xff0c;去掉中间的圆形遮盖 after 伪类元素即可。 一、构建基础样式 构建圆形节点和中间的遮盖元素。 <style>body {background-color: rgb(130, 226, 255);}.circle {top: 16…

个人网站展示(静态)

大学期间做了一个个人博客网站&#xff0c;纯H5编码的网站&#xff0c;利用php搭建了一个留言模块。 有需要源码的同学&#xff0c;可以联系我~ 首页&#xff1a; IT杂记模块 文人墨客模块 劳有所获模块 生活日志模块 关于我 一个推崇全栈开发的前端开发人员 微信: itrzzh …

蓝桥杯备战刷题five(自用)

1.数字三角形&#xff08;方向次数限制&#xff0c;动态规划&#xff09; //如果n为奇数时&#xff0c;最后必然走到最后行最中间的数&#xff0c;如果为偶数&#xff0c;则取中间两个数的最大值&#xff0c; //因为向左下走的次数与向右下走的次数相差不能超过 1 #include …

【动态规划】代码随想录算法训练营第四十四天 |完全背包,518. 零钱兑换 II , 377. 组合总和 Ⅳ (待补充)

完全背包理论基础 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完全背包和…

仿牛客网项目---项目总结

本篇文章是对整个项目的一个总结。下面这张图要好好理解。 整个项目都是构建在SpringBoot之上的&#xff0c;所以把它画到最底下&#xff0c;其它技术依托在springboot之上。但是springboot并不是技术的核心&#xff0c;而只是起到了一个辅助的作用&#xff0c;它的作用仅仅是降…

后端项目访问不了

问题&#xff1a; 后端启动不了&#xff0c;无法访问网站 原因&#xff1a; 1.防火墙没有关 2.有缓存 3、项目没有启动 4、docker没有启动 解决&#xff1a; 先查看进程&#xff1a;docker ps&#xff0c;必须有三个 详细查看&#xff1a;docker ps -a exited代表没有开启…

AI相关的实用工具分享

AI实用工具大赏&#xff1a;赋能科研与生活&#xff0c;探索AI的无限可能 前言 在数字化浪潮汹涌而至的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面&#xff0c;无论是工作还是生活&#xff0c;都在悄然发生改变。AI的崛起不仅为我们带…

怎么看待Groq

用眼睛看。 就是字面上的意思用眼睛看。 我属于第一波玩到的,先给大家一个直观的印象,Groq到底有多快。 目前Groq只能选Llama的70b,和Mixtral的MoE,那我选7*8的这个MoE模型来实验。 这么好些字大概花了不到1秒,流式响应,其实是不是流式已经没那么重要了 ,然后看每秒Toke…