链表
链表基础
定义:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
特点:
结点地址不连续
结点:
定义:组成链表的基本单元
组成:用户需要用的实际数据和下一个结点的地址
图示:
解析:
1.每个正方形代表一个结点、其上方的数字代表其在内存中的地址值。正方形的两层分别代表其数据内容以及用于指向下一个结点的指针。
2.如图,每个结点都存储着下个结点的地址,以此形成逻辑上的链状。
3.第一个正方形head代表头指针变量,用于存放链表中第一个结点的地址。
实现方式:链表用含指针的结构体实现。
例:
struct Node//声明结构体,用于模拟结点
{
char data;//用于存储数据,可以声明多个
struct Node *next;//用于存储下一个结点的地址
};
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*这个程序用来测试简单单向链表的创建及使用*/
struct Student//使用结构体来模拟结点的结构
{
int num;
float score;
struct Student *next;//用于存储下一结点的地址
};
int main()
{
struct Student a,b,c,*head,*p;//a,b,c作为结点,head作为头指针变量,p用于链接各结点
/*为各结点赋值*/
a.num=31001,a.score=89.5;
b.num=31003,b.score=90;
c.num=31007,c.score=85;
/*将结点链接为链表*/
head=&a;//这一步十分重要!链表必须要有头指针变量
a.next=&b,b.next=&c;//中间的每个结点都存储着下一个结点的地址
c.next=NULL;//c作为最后一个结点,为其next指针赋值为NULL以表示链表已到尽头
/*使用链表(输出链表中的值)*/
p=head;//使p指向链表的头一个结点
do
{
printf("%d %.1f\n",p->num,p->score);
p=p->next;//核心代码,使p指向链表的下一个结点。这样下一次循环将直接读取到新结点的数据。
}
while(p!=NULL);//当p==NULL即链表已到尽头。则不需要继续循环
return 0;
}
结果:
解析:链表的长度可变,结点可自行设计、增加、删除。使用十分灵活。
注:大部分演示以单向链表为例,方便理解。
链表操作
基础
核心:
1.通过指针访问链表
2.利用动态分配空间建立动态链表
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*这个程序用于演示结点控制基础*/
struct Student//结构体Student用于模拟链表结点
{
int num;
float score;
struct Student *next;
};
int main()
{
struct Student *p;//定义指针p用于操作链表结点
p=malloc(sizeof(struct Student));//利用malloc为结点动态分配空间
p->num=31001;//为链表结点添加数据
p->score=89.5;
printf("%d %.1f\n",p->num,p->score);//输出测试
free(p);//对于失去利用价值的结点,直接释放其内存空间
return 0;
}
结果: