C语言链表知识点(1)

嵌入式技术

1368人已加入

描述

链表知识1:

数组的特点:

空间连续,方便访问,只要知道首元素地址,就可以访问每个元素

数组的缺点:

需要提前分配固定大小的空间,一旦分配大小就不能改变 ,空间分配小了不够用,空间分配大了浪费空间

链表的概念:

由一个一个的结点组成,可以通过第一个节点就能访问所有节点(节点存储的是数据信息)每个节点是动态分配的,但是动态分配的空间不连续,通过一些方式来将每个节点连接起来就构成了链表

链表的节点:

节点空间是不连续,每个节点都存储下一个节点的地址要求每个节点可以存地址,还可以存需要存的数据,所以节点的类型一定是结构体类型

节点结构体:

至少要包含两个部分,一部分用于存储下一个节点的数据,一个用于存储下一个节点的地址。

定义一个节点数据结构体:

typedefstruct List Node_t;

struct List 
{
	/*数据区域有两个变量*/
	int a;
	float b;
	/*地址区域有一个指针*/
	Node_t *pNext;	 
};

这里容易犯一个错误,有挂结构体的嵌套可以参阅这篇博客。

结构体的嵌套问题 - 任智康 - 博客园 (cnblogs.com)

定义3个节点变量:

Node_t Head_Node; //表头变量 
Node_t Body_Node; //表身变量 
Node_t Tail_Node; //表尾变量

给每个节点变量赋值:

模拟链表操作把每个节点串联起来

Head_Node.a = 1;
	Head_Node.b = 1.0;
	Head_Node.pNext = &Body_Node; //头节点下一节点地址  
	
	Body_Node.a = 2;
	Body_Node.b = 2.0;
	Body_Node.pNext = &Tail_Node;//身体节点下一节点地址  
	
	Tail_Node.a = 3;
	Tail_Node.b = 3.0;
	Tail_Node.pNext =NULL;//尾节点后面没有节点 地址赋值NULL

通过给每个节点的数据赋值、然后把每个节点的地址指针赋值成下一节点的地址;最后一个节点的地址域赋值成空指针;

模拟链表操作访问每个节点:

Node_t *pTemp =  &Head_Node;
	
	while(pTemp != NULL)
	{
		Node_Count++; 
		printf("节点 %d 的信息:rn",Node_Count);
		printf(" int %drn float %frn Node_t* %prn",pTemp- >a,pTemp- >b,pTemp- >pNext);
		pTemp =  pTemp- >pNext;
	}

节点信息如下:

数组

如何插入1个节点:

用malloc函数开辟一段空间 把这个节点信息进行填充 根据添加的位置把他的

//插入一个节点插入到身体节点之后 尾巴节点之前 
	 	
	qTemp = (Node_t *)malloc(sizeof(Node_t)) ;
	
	qTemp- >a = 4;
	qTemp- >b = 4.0;
	
	//qTemp- >pNext = &Tail_Node;
	qTemp- >pNext = Body_Node.pNext;//插入的位置是尾巴节点之前 把尾巴节点的地址给当前节点
	
	
	Body_Node.pNext = qTemp; //把当前节点的地址给身体节点的下一节点 (插入到身体节点之后)

插入1个新的节点后的信息:

printf("rn===============第2次链表信息===============rn");
    pTemp = &Head_Node;
	while(pTemp != NULL)
	{
		Node_Count++; 
		printf("节点 %d 的信息:rn",Node_Count);
		printf(" int %drn float %frn Node_t* %prn",pTemp- >a,pTemp- >b,pTemp- >pNext);
		pTemp =  pTemp- >pNext;
	}
	Node_Count = 0;
	printf("rn===============第2次链表信息===============rn");

数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DIceA5SJ-1688555989623)(C:Users23206AppDataRoamingTyporatypora-user-imagesimage-20230704205520015.png)]

如何把刚才插入的1个节点删除:

把身体节点的下一个节点地址改成尾部节点,并且把开辟的空间给释放掉

Body_Node.pNext = &Tail_Node;
	free(qTemp);

删除掉这个节点后代码及运行效果

===============第1次链表信息===============
节点 1 的信息:
 int1
 float1.000000
 Node_t* 00007FF62E50D920
节点 2 的信息:
 int2
 float2.000000
 Node_t* 00007FF62E50D8F0
节点 3 的信息:
 int3
 float3.000000
 Node_t* 0000000000000000

===============第1次链表信息===============
第一次是三个节点
===============第2次链表信息===============
节点 1 的信息:
 int1
 float1.000000
 Node_t* 00007FF62E50D920
节点 2 的信息:
 int2
 float2.000000
 Node_t* 000001DCA6B3F540
节点 3 的信息:
 int4
 float4.000000
 Node_t* 00007FF62E50D8F0
节点 4 的信息:
 int3
 float3.000000
 Node_t* 0000000000000000

===============第2次链表信息===============
第二次是四个节点(添加了一个)
===============第3次链表信息===============
节点 1 的信息:
 int1
 float1.000000
 Node_t* 00007FF62E50D920
节点 2 的信息:
 int2
 float2.000000
 Node_t* 00007FF62E50D8F0
节点 3 的信息:
 int3
 float3.000000
 Node_t* 0000000000000000

===============第3次链表信息===============
第三次是三个节点(添加的节点又被删除了)

完整代码如下:

#include < stdio.h >
#include < stdlib.h >

typedefstruct List Node_t;

struct List
{
	/*数据区域有两个变量*/
	int a;
	float b;
	/*地址区域有一个指针*/
	Node_t* pNext;
};

Node_t Head_Node; //表头变量 
Node_t Body_Node; //表身变量 
Node_t Tail_Node; //表尾变量

Node_t* qTemp = NULL;

int Node_Count = 0;

int main(void)
{
	Head_Node.a = 1;
	Head_Node.b = 1.0;
	Head_Node.pNext = &Body_Node; //头节点下一节点地址  

	Body_Node.a = 2;
	Body_Node.b = 2.0;
	Body_Node.pNext = &Tail_Node;//身体节点下一节点地址  

	Tail_Node.a = 3;
	Tail_Node.b = 3.0;
	Tail_Node.pNext = NULL;//尾节点后面没有节点 地址赋值NULL 


	printf("rn===============第1次链表信息===============rn");
	Node_t* pTemp = &Head_Node;
	while (pTemp != NULL)
	{
		Node_Count++;
		printf("节点 %d 的信息:rn", Node_Count);
		printf(" int %drn float %frn Node_t* %prn", pTemp- >a, pTemp- >b, pTemp- >pNext);
		pTemp = pTemp- >pNext;
	}
	Node_Count = 0;
	printf("rn===============第1次链表信息===============rn");



	//插入1个节点插入到身体节点之后 尾巴节点之前 	
	qTemp = (Node_t*)malloc(sizeof(Node_t));

	qTemp- >a = 4;
	qTemp- >b = 4.0;

	//qTemp- >pNext = &Tail_Node;
	qTemp- >pNext = Body_Node.pNext;


	Body_Node.pNext = qTemp;


	printf("rn===============第2次链表信息===============rn");
	pTemp = &Head_Node;
	while (pTemp != NULL)
	{
		Node_Count++;
		printf("节点 %d 的信息:rn", Node_Count);
		printf(" int %drn float %frn Node_t* %prn", pTemp- >a, pTemp- >b, pTemp- >pNext);
		pTemp = pTemp- >pNext;
	}
	Node_Count = 0;
	printf("rn===============第2次链表信息===============rn");



	Body_Node.pNext = &Tail_Node;
	free(qTemp);



	printf("rn===============第3次链表信息===============rn");
	pTemp = &Head_Node;
	while (pTemp != NULL)
	{
		Node_Count++;
		printf("节点 %d 的信息:rn", Node_Count);
		printf(" int %drn float %frn Node_t* %prn", pTemp- >a, pTemp- >b, pTemp- >pNext);
		pTemp = pTemp- >pNext;
	}
	Node_Count = 0;
	printf("rn===============第3次链表信息===============rn");
	return0;
}

	while (pTemp != NULL)
	{
		Node_Count++;
		printf("节点 %d 的信息:rn", Node_Count);
		printf(" int %drn float %frn Node_t* %prn", pTemp- >a, pTemp- >b, pTemp- >pNext);
		pTemp = pTemp- >pNext;
	}
	Node_Count = 0;
	printf("rn===============第3次链表信息===============rn");
	return0;
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分