C语言——单向链表与增删改查

认识链表

·链表是可以动态地按需进行存储分配的一种结构。

·与数组相比较链表更加灵活,数组需要事先定义固定长度,而链表不需要。

·链表由数据域和指针域组成。数据域用来存放所需要的数据,指针域用来存放下一个结点的位置(地址)。

例子:创建一个关于学生信息的结构体,把此结构体当作链表的结点。

struct student
{
	char name[10];//姓名
	int weight;//体重
	int height;//身高
	int sex;//性别
	struct student* next;//用于存放下一结点的地址
};

形象点说就是每个结点都是一个岛屿,而你想去到下个岛屿时你得先知道下一个岛屿的位置。数据域是岛上的内容,指针域是岛上的路标,告诉你下一个岛屿的位置。

创建单向链表

单向链表的结构:
·头指针是链表的入口。

·每个结点通过其本身的指针访问下一个结点,因为其本身的指针存放着下一个结点的地址。

·头指针可不存放信息只记录下一结点地址。

·罗列一下我们要怎么创建一个链表。

  1. 为每个结点分配内存空间,创建一个结点。
  2. 记录链表的入口。
  3. 连接前后两个结点。
  4. 创建链表模块化

详细操作与解释如下:

struct student         这是链表结点的样子
{
	char name[10];//姓名
	int weight;//体重
	int height;//身高
	int sex;//性别
	struct student* next;//用于存放下一结点的地址
};
struct student* creatstu()  创建链表的函数
{
	struct student* head=NULL;//用来记录链表入口,创建完成后返回此指针
	struct student* p1;//用来创建新结点
	struct student* p2;//记录p1前一个结点
	int n = 0;//记录是否需要把结点地址赋予头指针
	p1 = p2 = (struct student*)malloc(sizeof(struct student));//为结点分配内存
	scanf("%s %d %d %d", p1->name,&p1->height, &p1->weight, &p1->sex);
	while (p1->height != 0)//停止创建的条件可自行调整
	{
		n++;
		if (n == 1)head = p1;//如果是第一个结点,他的地址要给到头指针
		else p2->next = p1;//如果不是便让p2得到p1结点的位置并连接,这样p1这个指针可以继续开辟新结点
		p2 = p1;//p2每次都走到p1结点,p1结点此时为最后结点
		p1= (struct student*)malloc(sizeof(struct student));//分配一个新的内存空间给p1,开创新结点
		scanf("%s %d %d %d",p1->name, &p1->height, &p1->weight, &p1->sex);
	}
	p2->next=NULL;//循环结束说明输入结束,此时p2为最后一个结点
	return head;//返回头指针
}

链表创建完成后返回头指针给调用该函数的函数,此时便可以通过访问头指针来访问整个链表。

·寻找时与数组的区别:链表的时间复杂度为O(n)(通过指针寻址一个一个寻找),数组为O(1)(知道下标直接访问)。

链表的增删改查


  1. 如何往已经创建好的链表中继续加入结点呢?有两种方法:头插法和尾插法。
struct student* stu()//创建学生结点 
{
	struct student* p;
	p = (struct student*)malloc(sizeof(struct student));
	p->next = NULL;
	return p;
}

头插法:使头指针指向新结点,新结点的指针指向原本第一个结点。

struct student* newstu=stu();//得到该新结点的地址
newstu->next=head->next;//先把新结点与原本的第一个结点连接
head->next=newstu;//再把头指针与新结点连接
为什么不能调转顺序?因为调转后无法连接原来的旧结点

尾插法:找到最后一个结点并连接

struct student* newstu=stu();//得到该新结点的地址
struct student* search=head;//设置一个用于搜索的指针
while(search->next!=NULL)search=search->next;//遍历链表,当其退出循环时便找到了最后一个
search->next-newstu;//连接两个结点

  1. 删除一个结点要先找到该节点,然后连接前后两个结点。
struct student* search=head,follow=head;//设置一个用于搜索的指针
while(search!=`````)//自行定义需删除结点的信息
{
	follow=search;//记录当前位置
	search=search->next;//寻找新位置
}
找到后:
follow->next=search->next;//连接两个结点
free(search)//释放该内存空间

  1. 同样设置一个用于搜索的指针,找到需要修改的信息即可。

  2. 设置用于搜索的指针进行遍历便可。

//只做一个粗略的介绍,具体的边界情况请自行讨论

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值