问题描述:
载30个人的船需要下去15人,这30人从1开始编号至30;
从1号开始报数,数到9的人淘汰,然后重新开始数,淘汰所有数到9的人,直至淘汰满15人。
解决思路:
本题如果采用条件判断的方式逻辑较复杂,所以这里采用更好理解的循环链表来解决。
1、首先创建头节点和尾节点
2、采用头插法的方式不断初始化链表
3、删除节点时采用双指针的方式
备注:上述三个步骤涉及链表的初始化、添加节点、删除节点等操作。
可以参考文章:数据结构:单链表的相关操作-CSDN博客
完整源码:
//游戏规则,载30个人的船需要下去15人,这30人从1开始编号至30.
//从1号开始报数,数到9的人淘汰,然后重新开始数,淘汰所有数到9的人,直至淘汰满15人
#include<stdio.h>
#include<stdlib.h>
typedef struct info //尝试使用循环链表实现
{
int id;
struct info* next;
}info;
int main()
{
info* head = malloc(sizeof(info));//首先创建头节点和尾节点
info* end = malloc(sizeof(info));
head->id = 1; //初始化id
end->id = 30;
head->next = end;
end->next = head;
//循环链表的初始化
info* current = end;
for (int i = 0; i < 28; i++)//通过头插法的方式不断添加新的节点
{
info* newnode = malloc(sizeof(info));
newnode->id = 29 - i;
newnode->next = current;
head->next = newnode;
current = newnode;
}
//打印节点信息
printf("初始存活情况为:\n");
info* p1 = head;
for (int i = 0; i < 30; i++)
{
printf("%d ", p1->id);
p1 = p1->next;
}
printf("\n");
//寻找淘汰的节点
info* p2 = head->next; //采用双指针的方式删除节点
int out_man = 0;
int times = 1;
while (out_man < 15)
{
times++;
if (times == 9)
{
out_man++; //总的淘汰人数+1
info* temp = p2;//说明p2这个节点是需要被删除的,将其记录为temp
printf("%d号被淘汰了\n", temp->id);
p2 = p2->next;
p1->next = p2;
free(temp); //淘汰这个人
times = 0; //淘汰一个人后重新计数
}
else//双指针后移
{
p1 = p2;
p2 = p2->next;
}
}
return 0;
}