C语言链表1

1、链表的引入

1.1、数组的缺陷
(1)数组有两个缺陷:一个数组中所有的元素类型必须一致;数组中的元素个数必须事先制定并且一旦制定之后不能更改
(2)数组缺陷的解决方法:第一个缺陷靠结构体去解决,结构体允许的元素的类型不相同。
(3)数组缺陷的解决方法:第二个缺陷制作链表,因为链表实际上就是一个元素个数可变的数组。
1.2、链表是怎样的
(1)链表就是用锁链连接起来的表。这里的表指的是一个一个的节点,节点中有一些内存可以用来存储数据;这里的锁链指的是链接各个表的方法,C语言中用来连接2个表的方法就是指针。
(2)链表是若干个节点组成的(链表的各个节点结构是完全类似的),节点是由有效数据和指针组成的。有效数据区域用来存储信息完成任务的,指针区域用于指向链表的下一个节点从而构成链表。
1.3、链表的作用
(1)链表就是解决数组大小不能动态扩展的问题,所以其实链表就是当数组用。链表能完成的用数组也能完成,数组能完成的链表也可以,但是链表比数组灵活。
(2)链表就是用来存储数据的,链表的优势是灵活,数组的优势是使用简单
1.4、单链表的实现
1.4.1、单链表的节点构成
(1)链表是由节点构成的,节点中包含:有效数据和指针。

#include <stdio.h>

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

(2)定义的struct node只是一个结构体,本身没有变量生成,也不占用内存。结构体定义相当于为链表定义了一个模板,但是还没有一个节点,将来在实际创建链表时需要一个节点时用这个模板来复制一个即可。

1.4.2、堆内存的申请和使用
(1)链表的内存要求比较灵活,不能用栈,也不能用data数据段。只能用堆内存。
(2)使用堆内存来创建一个链表节点的步骤:

1、申请堆内存,大小为一个节点的大小(检查申请结果是否正确);
2、清理申请到的堆内存;
3、把申请到的堆内存当作一个新节点;
4、填充你这个新节点的有效数据和指针区域。
#include <stdio.h>

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

int main(void)
{
	//创建一个链表节点
	struct node *p=(struct node*)malloc(sizeof(struct node));
	if(NULL==p)
	{
		printf("malloc error:\n");
		return -1;
	}
	
	//清理申请到的堆内存
	bzero(p, sizeof(struct node));

	//填充节点
	p->data=1;
	p->pnext=NULL;		//将来要指向下一个节点的首地址
						//实际操作中将下一个节点malloc返回的指针赋值给这个即可
	
}

1.4.3、链表的头指针
(1)头指针并不是节点,而是一个普通指针,只占4字节。头指针的类型是struct node *类型的,所以它才能指向链表的节点。
(2)一个典型的链表的实现就是:头指针指向链表的第1个节点,然后第1个节点中的指针指向下一个节点,然后依次类推一直到最后一个节点。这样就构成了一个链。
1.4.4、实战:构建一个简单的单链表

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

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

int main(void)
{
	//定义指针
	struct node *pHeader=NULL;

	//创建一个链表节点
	struct node *p=(struct node*)malloc(sizeof(struct node));
	if(NULL==p)
	{
		printf("malloc error:\n");
		return -1;
	}
	
	//清理申请到的堆内存
	bzero(p, sizeof(struct node));

	//填充节点
	p->data=1;
	p->pnext=NULL;		//将来要指向下一个节点的首地址
						//实际操作中将下一个节点malloc返回的指针赋值给这个即可
	
	pHeader=p; 			//将本节点和它前面的头指针关联起来


	//每创建一个新的节点,把这个新的节点和它前一个节点关联起来
	//创建一个链表节点
	struct node *p1=(struct node*)malloc(sizeof(struct node));
	if(NULL==p1)
	{
		printf("malloc error:\n");
		return -1;
	}
	
	//清理申请到的堆内存
	bzero(p1, sizeof(struct node));

	//填充节点
	p1->data=2;
	p1->pnext=NULL;		//将来要指向下一个节点的首地址
						//实际操作中将下一个节点malloc返回的指针赋值给这个即可
	
	p->Next=p2; 			//将本节点和它前面的头指针关联起来


	//每创建一个新的节点,把这个新的节点和它前一个节点关联起来
	//创建一个链表节点
	struct node *p2=(struct node*)malloc(sizeof(struct node));
	if(NULL==p2)
	{
		printf("malloc error:\n");
		return -1;
	}
	
	//清理申请到的堆内存
	bzero(p2, sizeof(struct node));

	//填充节点
	p2->data=3;
	p1->pnext=p2;		//将来要指向下一个节点的首地址
						//实际操作中将下一个节点malloc返回的指针赋值给这个即可
	
	//至此创建了一个有1个头指针+3个完整节点的链表


	//访问链表中的各个节点的有效数据,这个访问必须注意不能使用p、p1、p2,而只能使用pHeader。

	//访问链表第1个节点的有效数据
	printf("node1 data:%d.\n",pHeader->data);
	printf("p->data:%d.\n",p->data);					//pHeader->data等同于p->data
	
	//访问链表第2个节点的有效数据
	printf("node1 data:%d.\n",pHeader->pNext->data);
	printf("p->data:%d.\n",p1->data);					//pHeader->pNext->data等同于p1->data

	//访问链表第3个节点的有效数据
	printf("node1 data:%d.\n",pHeader->data);
	printf("p->data:%d.\n",p2->data);					//pHeader->pNext->data等同于p2->data
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值