目录
一、什么是链表和链式存储结构
1、链表是通过一组任意的存储单元来存储线性表中的数据元素,是通过链式存储结构进行存储。
就是通过下图一个结点连起来,像铁链子一样。
2、链式存储结构是不要求逻辑上相邻的数据元素在物理位置上也一定相邻,它是通过"链"建立起数据元素之间的逻辑联系的,对线性表的插入、删除不需要移动数据元素,因此它没有顺序存储结构所具有的弱点。
二、链表的多种操作(直接上代码)
1、数据域和指针域
存放数据元素信息的称为数据域,存放其后继续地址的称为指针域。
typedef struct DataType
{
long long number ; //存储ISBM
char name[64]; //存储图书名
int price; //存储定价
}DataType;
typedef struct Lnode
{
DataType data; //数据域
struct Lnode *next; //指针域
}Lnode;
2、变量初始化
Lnode *head; //全局变量
int num=0; //全局变量,表示结点个数
void Init_Link()
{
head=(Lnode *)malloc(sizeof(Lnode));
head->next=NULL;
}
3、链表创建
head指向头结点,p=head;使p指向head;head的next也就指针域存储下一个结点的地址即图中的q,p=q,使p指向q,便于下个结点连接,
void Create_Link()
{
Lnode *p,*s;
p=(Lnode *)malloc(sizeof(Lnode));
p=head; //使p指向head
int i;
printf("请输入结点的个数:\n");
scanf("%d",&num); //输入结点个数
printf("请输入图书的ISBM、图书名、定价:\n"); //ISBM为图书编号
for(i=1;i<=num;i++)
{
s=(Lnode *)malloc(sizeof(Lnode));
scanf("%lld%s%d",&s->data.number,s->data.name,&s->data.price);
p->next=s;
p=s;
s->next=NULL;
}
}
4、输出
void Print_Link()
{
Lnode *p=NULL;
p=head; //保留head的初值
int i;
if(head->next==NULL) //判断链表是否为空
{
printf("链表为空\n");
}
else{
printf("输出图书的ISBM 图书名 定价:\n");
for(i=1;i<=num;i++)
{
printf("%lld %s %d\n",head->next->data.number,head->next->data.name,head->next->data.price);
head=head->next;
}
head=p; //把head保持初值,便于数据的输出
}
}
5、插入
链表的插入如下图所示,算法:s->next=p;q->next=s;
void Insert_Link()
{
int i;
long long c;
int mark=0; //插入时的标志位
Lnode *p=NULL,*s;
s=(Lnode *)malloc(sizeof(Lnode));
p=head; //保留head的初值
if(head->next==NULL) //判断链表是否为空
{
printf("请输入所要插入图书的ISBM、图书名、定价:\n");
scanf("%lld%s%d",&s->data.number,s->data.name,&s->data.price);
num++;
head->next=s;
s->next=NULL;
}
else{
printf("输入在那个ISBM之后插入:\n");
scanf("%lld",&c);
while(head->next!=NULL)
{
if(head->next->data.number==c)
{
printf("请输入图书的ISBM、图书名、定价:\n");
scanf("%lld%s%d",&s->data.number,s->data.name,&s->data.price);
s->next=head->next->next;
head->next->next=s;
num++; //插入成功,结点个数加一
printf("插入成功\n");
mark=1;
break;
}
head=head->next;
}
if(mark==0) //插入失败时
{
printf("图书ISBM无,插入失败\n");
}
head=p; //把head保持初值,便于数据的输出
}
}
6、删除
l链表的删除如下图所示,把p删掉,q->next=s(s等于p->next);
void Delete_Link()
{
Lnode *p=NULL,*t=NULL;
long long c; //定义输入所要删除的ISBM
p=head;
int mark=0; //删除时的标志位
if(head->next==NULL) //判断链表是否为空
{
printf("链表为空\n");
} else{
printf("输入所要删除的ISBM:\n");
scanf("%lld",&c);
while(head->next!=NULL)
{
if(head->next->data.number==c)
{
num--; //删除了,结点个数减一
t=head->next;
head->next=head->next->next;
mark=1;
free(t); //释放存储空间
printf("删除成功\n");
break;
}
head=head->next;
}
if(mark==0)
{
printf("删除失败\n");
}
head=p;
}
}
7、查找
void Find_Link()
{
Lnode *p=NULL;
long long int c; //定义所要输入所要插入的ISBM
p=head;
if(head->next==NULL) //判断链表是否为空
{
printf("链表为空\n");
}
else{
printf("输入所要查找的ISBM:\n");
scanf("%lld",&c);
while(head->next!=NULL)
{
if(head->next->data.number==c)
{
printf("ISBM:%lld 图书名:%s 定价:%d\n",head->next->data.number,head->next->data.name,head->next->data.price);
break;
}
head=head->next;
}
head=p;
}
}
8、总结
进行简单的复习一下链表的思维,真的会有很多收获。