(一)前提
41个人报数,1-3,当谁报数为3,谁就去嗝屁。现在获取他们嗝屁的顺序
(二)实现结构





(三)代码实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef int Status;
typedef struct Node
{
ElemType data;
struct Node* next;
}Node;
typedef struct Node* CLinkList;
//四个基本操作,初始,清空,判断是否为空,获取长度
Status InitList(CLinkList* L, int n);
//指定开始位置来打印数据
void PrintListByIndex(CLinkList rear, int index);
//用来打印链表
void PrintList(CLinkList rear);
老方法声明函数,结构体等
int main()
{
CLinkList L = NULL;
CLinkList p;
ElemType e;
int n = 41;
int m = 3;
int i;
InitList(&L,n); //现在L指向第一个结点
PrintList(L);
while (L!=L->next) //判断头尾指针是否指向相同,相同则元素都不存在
{
for (i = 1; i < m-1; i++)
L = L->next; //找到要删除的那个结点的前一个
printf("%d->", L->next->data); //获取被杀死的人的数据
p = L->next; //获取被杀死的人
L->next = p->next;
free(p);
L = L->next;//指向新的下一个元素
}
printf("%d", L->data); //输出最后一个
free(L);
system("pause");
return 0;
}
//四个基本操作,初始,清空,判断是否为空,获取长度
//初始化不带头结点的链表
Status InitList(CLinkList* L,int n)
{
CLinkList rear, q; //rear是尾结点
ElemType item;
rear = q = NULL;
srand(time(0));
for (int i = 0; i < n;i++)
{
item = rand() % 100;
if (*L==NULL)
{
*L = (CLinkList)malloc(sizeof(Node));
if (!(*L))
return ERROR;
(*L)->data = item;
(*L)->next = *L; //自己指向自己
rear = *L; //设置尾指针位置
}
else
{
//生成新的节点,根据尾指针添加节点,并实时更新尾指针。注意这里数据插入是尾插法
q = (CLinkList)malloc(sizeof(Node));
q->data = item;
q->next = rear->next;
rear->next = q;
rear = q;
}
}
return OK;
}

//用来打印链表
void PrintList(CLinkList L)
{
CLinkList q = L; //获取头指针
while (q->next != L)
{
printf("%d ", q->data);
q = q->next;
}
printf("%d
", q->data);
}
老方法打印链表PrintList

(四)扩展提升
1-N个人,按顺时针一圈,每个人手中有一个密码(一个正整数),
我们(裁判)定义第一个开始值为M,从第一个人开始自1开始报数,直到报数为M,那么这个人就退出,将他手中的密码值作为新的开始值,
一直循环直到所有的人都退出
情景演示






修改代码
int main()
{
CLinkList L = NULL;
CLinkList p;
ElemType e;
int n = 19;
int m;
int i;
InitList(&L, n); //现在L指向第一个结点
PrintList(L);
scanf("%d", &m); //初始密码值我们输入
m--; //下面while循环都是由前一结点开始计算距离的,而我们这里是从第一个结点直接开始的,需要找到他的前一个节点,或者将走的步数减一即可
while (L != L->next) //判断头尾指针是否指向相同,相同则元素都不存在
{
for (i = 1; i <= m - 1; i++)
L = L->next; //找到要退出的那个人的前一个人
printf("%d->", L->next->data); //获取将要退出的人的密码
p = L->next; //获取即将退出的人
L->next = p->next;
m = p->data; //更新密码值
free(p);
//每次返回的都是退出结点的前一个节点,方便计算当密码为1的情况(重点)
}
printf("%d
", L->data); //输出最后一个人
free(L);
system("pause");
return 0;
}
