链表的定义:首先链表是一种常见的基础数据结构 ,是一种线性 表,但与数组的整齐性和连续性不同,链表是一种在物理储存单元上非顺序,非连续的存储结构,而链表中的数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表的组成部分:链表由一系列结点(链表中的每一个元素即成为结点)组成,其中结点包括两个部分:数据域与指针域。
1.由于链表中的每个结点(一般不包括头结点和尾结点):都包括数据域和指针域两个部分,及即存数值又存指针,所以首先需要一个结构体来表示每个结点;
typedef struct student
{
int number;
struct student *next;
}stu;
2.由于链表的建立是一种从无到有的过程,并且每个链表所需要内存空间都是不同且不可确定的,所以需要一个函数为数据开辟新的内存空间,此时则需要了解两种开辟内存空间的函数;
<1>malloc函数
void *malloc(unsigned int size)
向系统申请分配指定size个字节的内存空间,返回值为void *类型(可以强制转换为任何其他类型的指针)
<2>calloc函数
void *calloc(unsigned int n,unsigned int size)
向系统申请分配连续空间的size个字节的n个内存空间,返回值为void *类型(可以强制转换为任何其他类型的指针)
注意:这两个函数的包含文件由于编译器版本的不同可能有两种
#include<stdlib.h>
#include<malloc.h>
3.头插法的主要思想:
将所输入的数据均插入前一个输入数据的前边;
缺点:正常传统输出时为逆序输出;
解决方法:新增一个依次指向,使其正序输出;
b->number=n;
b->next=NULL;
if(head->next==NULL)
{
head->next=b;
}
else
{
a->next=b;
}
a=b
4.内存空间的释放:free()
之前申请的内存空间用完之后,及时将他释放
free(head);
5.头插法的整体代码及解释
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>//开辟内存空间的malloc函数的头文件
typedef struct student
{
int number;//数据域
struct student *next;//指针域
}stu;//定义一个结构体,其中包括数据与指针
main()
{
stu *head=(stu *)malloc(sizeof(stu));//为头指针开辟内存空间
head->next=NULL;//头指针的下一个指向空指针NULL
int n;
while(scanf("%d",&n)&&n!=-1)//只要输入的数字不为-1即表示继续输入
{
stu *a;
stu *b=(stu *)malloc(sizeof(stu));//为插入的结构体等开辟新的内存空间
b->number=n;//将n赋值给开辟出空间中的数值部分
b->next=NULL;//将开辟出新内存空间的指针域指向空
if(head->next==NULL)
{
head->next=b;
}//只在最开始进行一次
else
{
a->next=b;
}
a=b;//通过指针指向将a插在b之前
}//由于每次均在前一个值的前边插入,故称之为:头插法
stu *z=head->next;//定义一个新的指针指向头指针的下一个指针域
while(z!=NULL)//只要此指针不为空即进行循环
{
printf("%d ",z->number);//指向数据域
z=z->next;//每循环一次向后移一位
}
free(head);
}