🍅一.自我介绍
大家好,我是你们老朋友大鹏,还有一周的时间就要进行蓝桥杯的省赛了,而这比赛前的一周时间就显得非常关键,把握好这些时间,你可能直接会在省赛中大放光彩,关注我,这一周带着你夺奖冲刺。
🍅二.什么是链表
链表是线性表的链式存取的数据结构,是一种链式存取的数据结构,是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:数据域(数据元素的映象)+ 指针域(指示后继元素存储位置),数据域就是存储数据的存储单元,指针域就是连接每个结点的地址数据。 相比于线性表顺序结构,操作复杂。我们用两张图对比一下线性表的顺序储存结构和链表在内存中存储的差别。
🍅三.链表的结构
🍅四.链表的实战
通过上面的介绍,大家可能还是不太能理解为什么要使用链表或者还不懂什么是链表,我们用一个题目来引入。
✌1.首先我们需要进行节点定义
typedef struct Node
{
int data;//存放整形数据
struct Node* next;//定义指针指向下一个节点
}Node;
✌2.我们需要构成一整个链表
head-> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
Node * head=(Node*)malloc(sizeof(struct Node));//先生成头节点
void init()//初始化
{
head->next = NULL; //形成空链,由上文已知单链表最后一个结点的指针为空。
for (int i = 10; i >= 1; i--)
{
Node *temp = (Node*)malloc(sizeof(struct Node));
temp->data = i;
temp->next = head->next;
head->next = temp;
}
}
✌3.写一个插入函数
void insert(int x)
{
Node* p=(struct Node*)malloc(sizeof(struct Node));//新建一个结点
p->data=x; //把数据域赋值为x
p->next=head->next;//将节点加入到链表中
head->next=p;
}
✌4.我们要写一个删除函数,通过遍历链表删掉想要的数字
void del(int x)
{
Node* Before=head;//定义前驱节点
for(Node* T=head->next;T!=NULL;T=T->next)
{
if(T->data=x)
{
Node* Temp=T;
Before->next=T->next;
free(Temp);//释放掉该结点
Temp=NULL;
return;
}
else
Before=T;//若未找到则改变前驱节点
}
✌5.我们写一个遍历输出函数,形式接近于删除函数
void print()
{
for(Node* T=head->next;T!=NULL;T=T->next;)//遍历整个链表
{
printf("%d ",T->data);
}
}
✌6.我们编写主函数
int main()
{
int M,input;
scanf("%d",&M);
for(int i=1;i<=M;i++)
{
scanf("%d",&input);
del(input);
insert(input)
printf("这是排序第%d次的结果\n",i);
print();
}
return 0;
}
✌7.完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;//存放整形数据
struct Node* next;//定义指针指向下一个节点
}Node;
Node* head = (Node*)malloc(sizeof(struct Node));//先生成头节点
void init()//初始化
{
head->next = NULL; //形成空链,由上文已知单链表最后一个结点的指针为空。
for (int i = 10; i >= 1; i--)
{
Node* temp = (Node*)malloc(sizeof(struct Node));
temp->data = i;
temp->next = head->next;
head->next = temp;
}
}
void insert(int x)
{
Node* p = (struct Node*)malloc(sizeof(struct Node));//新建一个结点
p->data = x; //把数据域赋值为x
p->next = head->next;//将节点加入到链表中
head->next = p;
}
void del(int x)
{
Node* Before = head;//定义前驱节点
for(Node* T = head->next;T != NULL;T = T->next)
{
if (T->data = x)
{
Node* Temp = T;
Before->next = T->next;
free(Temp);//释放掉该结点
Temp = NULL;
return;
}
else
Before = T;//若未找到则改变前驱节点
}
}
void print()
{
for (Node* T = head->next;T != NULL;T = T->next)//遍历整个链表
{
printf("%d ",T->data);
}
printf("\n");
}
int main()
{
int M,input;
init();
scanf("%d",&M);
for (int i = 1;i <= M;i++)
{
scanf("%d",&input);
del(input);
insert(input);
printf("这是排序第%d次的结果\n",i);
print();
}
return 0;
}
✌8.运行截图
🍅五.总结
使用链表不仅可以减少时间复杂度,并且对一些适用性的问题相比数组来说要更加简便,效率也会更高。这在比赛中会大大减少我们接菌问题的时间