数组是一段连续的内存空间。在使用时必须要定义固定大小的空间,造成的问题是不仅运行时元素的移动量大还会造成一定内存空间的浪费。这时就引入了链表的概念。
链表是一种可以在保证数据的逻辑顺序不变的前提下,实现动态存储分布的存储方式,即一组数据不改变逻辑顺序,但是存储单元可以连续,也可以不连续。因此使用链表可以节省内存空间,提高数据操作效率。
题目链接:约瑟夫问题 - 洛谷
一、题目详情:
题目:n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
输入格式:两个整数m和n,m>=1,n<=100。
输出格式:n个整数,按顺序输出每个出圈人的编号。
二、代码的编写
#include<stdio.h>
#include<stdlib.h> //便于使用动态内存分配函数
typedef struct note
{
int date;
struct note *next;
}L; //使用结构体定义链表节点
int main()
{
int n,m,i;
L*head=(L*)malloc(sizeof(int)); //为指针分配int存储空间
L*p;L*c;
scanf("%d%d",&n,&m);
head->date=1;
head->next=NULL;
c=head;
for(i=2;i<=n;i++)
{
p=(L*)malloc(sizeof(int));
p->date=i;
p->next=c->next;
c->next=p;
c=p;
}
c->next=head; //建立链表完成
L*now=head;L*prev=head;
while((n--)!=1)
{
int j=1;
for(i=1;i<m;i++)
{
prev=now;
now=now->next;
}
prev->next=now->next;
printf("%d ",now->date);
free(now); //找出要出列的节点并释放
now=prev->next;
}
printf("%d",now->date);
free(now); //将最后一个节点释放
return 0;
}
编译预处理命令:#include<stdlib.h>
包含动态内存分配函数(malloc、colloc、free、realloc)等。
typedef语句:重新定义变量类型名,原类型名仍可使用。
本题中typedef用于重新定义结构体类型名,struct note和L均属于结构体类型名
malloc函数:(类型名*)malloc(所需的内存字节数)
功能:分配所需字节长度的存储单元块
(类型名*)功能:强制类型转换成所需类型的指针
free函数:free(指针变量)
功能:释放指针所指的存储单元块(必须是由动态内存分配函数一次性分配的全部单元)
结果测试图
三、 结束语
若大家阅读本文时发现错误或遇到问题,欢迎到评论区留言,大家一起解决问题,共同进步,不断提高!!