链表

链表是一种动态数据结构,通过指针连接节点以解决数组大小不可动态扩展的问题。本文介绍了链表的概念,强调了其灵活性,并详细讲解了在C语言中如何创建和插入节点到单链表中,包括在链表尾部和头部插入节点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表就是一个元素个数可以实时变大/变小的数组
链表就是被锁链链接起来的表。这里的表指的是一个一个的节点,节点内的一些内存可以用来存储数据;这里的锁链指的是链接各个表的方式,C语言中用指针来链接2块内存

链表是由若干个节点组成的,节点由有效数据和指针组成(节点结构完全类似),有效数据用来存储信息完成任务的,指针区域用于指向链表的下一个节点而构成链表

总结
链表本质上就是用来解决数组的大小不能动态扩展的问题,所以链表其实就是当数组用的。
链表就是用来存储数据的,链表用来存数据相对于数组来说有点就是灵活性,需要多少个动态分配多少个,不占用额外内存。

单链表的实现
单链表
定义的struct node只是一个机构体,本身没有变量生成,也不占用内存。结构体定义相当于为链表节点定义了一个模板,但是还没有一个节点,将来在实际创建链表时需要一个节点时用这个模板来赋值一个即可
链表的内存需求比较灵活,只能使用堆内存:malloc申请堆内存,大小为一个节点大小,清理申请到的堆内存,把申请到的堆内存当做一个新节点,填充新节点的有效数据和指定区域

#include<stdio.h>

//构建一个链表的节点
struct node
{
	int data; //有效数据
	struct node *pnext;  //指向下一个节点的指针
};

int main(void)
{
	//定义头指针
	struct node *header = NULL;
	
	//创建一个链表节点
	struct node *p=(struct node*)(malloc(sizeof(struct node));
	if(NULL==p)
	{
		printf("malloc error.\n");
		return -1;
}
//清理申请到的堆内存
bzero(p,sizeof(struct ndoe));
//填充节点
 p->data = 1;
 p->pnext = NULL;  //下一个节点不知道是啥,所以暂时指向NULL   (下一个节点的首地址)

 header = p; //p是第一个节点的首地址,p赋值给header 相当于将头指针和首地址链接起来


	return 0 ;
};

头指针 header 只是一个指针,指向第一个节点的首地址,只占四个字节,头指针的类型是 struct node *

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
//构建一个链表的节点
struct node
{
	int data; //有效数据
	struct node *pnext;  //指向下一个节点的指针
};

int main(void)
{
	//定义头指针
	struct node *header = NULL;
	
	//创建一个链表节点`
	struct node *p1=(struct node*)(malloc(sizeof(struct node));
	if(NULL==p1)
	{
		printf("malloc error.\n");
		return -1;
}
//清理申请到的堆内存
bzero(p1,sizeof(struct ndoe));
//填充节点
 p1->data = 2;
 p1->pnext = NULL;  //下一个节点不知道是啥,所以暂时指向NULL   (下一个节点的首地址)

 header = p1; //p是第一个节点的首地址,p赋值给header 相当于将头指针和首地址链接起来


	//创建一个链表节点
	struct node *p2=(struct node*)(malloc(sizeof(struct node));
	if(NULL==p2)
	{
		printf("malloc error.\n");
		return -1;
}
//清理申请到的堆内存
bzero(p2,sizeof(struct ndoe));
//填充节点
 p2->data = 3;
 p2->pnext = NULL;  //下一个节点不知道是啥,所以暂时指向NULL   (下一个节点的首地址)
 p1->pnext = p2;

	//创建一个链表节点
	struct node *p3=(struct node*)(malloc(sizeof(struct node));
	if(NULL==p3)
	{
		printf("malloc error.\n");
		return -1;
}
//清理申请到的堆内存
bzero(p3,sizeof(struct ndoe));
//填充节点
 p3->data = 3;
 p2->pnext=p3;
 p3->pnext = NULL;
	return 0 ;
};

在这里插入图片描述

访问链表第一个节点的有效数据
printf(“node data %d\n”,header->data); //等同于 p1->data
访问链表第二个节点的有效数据
printf(“node data %d\n”,header->pnext->data); //headerp1 p1->pnext->p2 p2->data
访问链表第三个节点的有效数据
printf(“node data %d\n”,header->pnext->pnext->data); //header
p1 p1->pnext->p2 p2->pnext->p3 p3_data

只能通过头指针来访问链表里面的数据,不能直接用各自的指针,因为在程序中我们保存链表是不会保存各个节点的指针的。 前一个节点内部的pnext指针能帮助我们找到下一个节点
单链表算法之插入节点
将创建节点的代码封装成一个函数

简单理解版:

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
//构建一个链表的节点

struct node
{
	int data; //有效数据
	struct node *pnext;  //指向下一个节点的指针
};




//作用:创建一个链表节点     返回值:struct node * ,指针指向我们本函数新创建的一个节点的首地址
struct node *creat_node(int data)
{
	struct node *p1=(struct node *)malloc(sizeof(struct node));
	if(NULL=p1)
	{
		printf("error\n");
		return NULL;
	}
	bzero(p1,sizeof(struct node));
	p1->data=data;
	p1->pnext=NULL;

	return p1;
	
}
struct node *creat_node2(int data)
{
	struct node *p2=(struct node*)malloc(sizeof(struct node));
	if(NULL==p2)
	{
		printf("malloc error.\n");
		return NULL;
}
  	bzero(p2,sizeof(struct ndoe));
	//填充节点
	 p2->data = 2;
	 p2->pnext = NULL;  //下一个节点不知道是啥,所以暂时指向NULL   (下一个节点的首地址)

	return p2;
}

struct node *creat_node3(int data)
{
	struct node *p3=(struct node*)malloc(sizeof(struct node));
	if(NULL==p3)
	{
		printf("malloc error.\n");
		return NULL;
	}
//清理申请到的堆内存
	bzero(p3,sizeof(struct ndoe));
	//填充节点
	 p3->data = data;
	 p3->pnext = NULL;
	return p3;
}
int main(void)
{
	//定义头指针
	struct node *header = NULL;
	header = creat_node(1);  //等同于 header=p1
	header->pnext=creat_node2(2);
	header->pnext->pnext=creat_node3(3);

	return 0 ;
}

正常版

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
//构建一个链表的节点

struct node
{
	int data; //有效数据
	struct node *pnext;  //指向下一个节点的指针
};


struct node *creat_node(int data)
{
	struct node *p=(struct node *)malloc(sizeof(struct node));
	if(NULL=p)
	{
		printf("error\n");
		return NULL;
	}
	bzero(p,sizeof(struct node));
	p->data=data;
	p->pnext=NULL;

	return p;
	

}
int main(void)
{
	struct node *header=NULL;
	header=creat_node(1);
	header->pnext=creat_node(2);
	header->pnext->pnext=creat_node(3);
	return 0;
}

头部插入和尾部插入
在链表尾部插入新节点

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
//构建一个链表的节点

struct node
{
	int data; //有效数据
	struct node *pnext;  //指向下一个节点的指针
};


struct node *creat_node(int data)
{
	struct node *p=(struct node *)malloc(sizeof(struct node));
	if(NULL=p)
	{
		printf("error\n");
		return NULL;
	}
	bzero(p,sizeof(struct node));
	p->data=data;
	p->pnext=NULL;

	return p;

}

void insert_tail(struct node *ph,struct node *new)
{
	//先找到链表中最后一个节点
	struct node *p = ph;
	while (NULL !=p->pnext)
	{
		p=p->pnext;
	}
	//将最后一个插入尾部
	p->pnext = new;
}
int main(void)
{
  //	struct node *header=NULL;
  struct node *header = creat_node(1);
  	insert_tail(pHeader, create_node(2));
	insert_tail(pHeader, create_node(3));
	insert_tail(pHeader, create_node(4));
	header=creat_node(2);
	header->pnext=creat_node(3);
	header->pnext->pnext=creat_node(4);
	return 0;
}

在链表头部插入新节点

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
//构建一个链表的节点

struct node
{
	int data; //有效数据
	struct node *pnext;  //指向下一个节点的指针
};


struct node *creat_node(int data)
{
	struct node *p=(struct node *)malloc(sizeof(struct node));
	if(NULL=p)
	{
		printf("error\n");
		return NULL;
	}
	bzero(p,sizeof(struct node));
	p->data=data;
	p->pnext=NULL;

	return p;

}

void insert_head(struct node *ph,struct node *new)
{
	//新节点的pnext指向原来的第一个节点
	new->pnext=ph->pnext;
	//头节点的next指向新节点地址
	ph->pnext=new;
	//头节点的计数+1
	ph->data +=1;
}
int main(void)
{
	struct node *header = creat_node(0);
	insert_head(pHeader, create_node(1));
	insert_head(pHeader, create_node(2));
	insert_head(pHeader, create_node(3));
	return 0;
}
	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值