#include<stdio.h>
#include<stdlib.h>
struct number// 声明一个结构体,在结构体中写入一个本类型的指针,做成链表
{
int num;
struct number *next;
};
struct number * INPUT( int n);//创建一个链表,将猴子的序号都存入链表中 关键是要做成循环链表 最后一个节点的下一个应该指向头节点
void SELECT(struct number *headptr, int n);// 利用循环等手段 进行筛选大王
int main()
{
int n;
printf("有:");
scanf_s("%d", &n);
while (getchar()!= '\n') // 保证了不正确的输入
continue;
printf("参加游戏\n");
SELECT(INPUT(n), n);// 调用相应函数 执行功能
getchar();
getchar();
return 0;
}
struct number * INPUT( int n)
{
struct number *headptr = NULL,*prev,*current;
for (int i = 1; i <= n;i++)//循环分别进行申请内存
{
current = (struct number*)malloc(sizeof(struct number));
if (current != NULL)
{
current->num = i;
if (headptr == NULL)// 第一节链节 要特别说明
{
headptr = current;
}
else// 之后的链节
{
prev->next = current;
}
current->next = NULL;// 这里一定要把最后一节的后面一个链节设为NULL
prev = current;// 一定要有这一步 要不在第一个链节创建完之后 会显示prev为NULL
}
}
current->next = headptr;// 使链表循环起来
return headptr;
}
void SELECT(struct number *headptr, int n)
{
struct number *prev = NULL, *current = NULL;
int count = 0;
current = headptr;
while (current->next != headptr)
{
current = current->next;//将current指向最后一个
}
while (current != current->next)
{
prev = current;//是prev指向current前一个 从而进行后面的一个一个向后退的步骤
current = current->next;
count++;// 计数器 也就是游戏规则 数4次的猴子出局
if (count % 4 == 0)
{
printf("%d被淘汰\n",current->num);
prev->next = current->next;
free(current);// 释放内存
current = prev;
}
}
printf("%d是大王\n", current->num);
free(current);
return;
#include<stdlib.h>
struct number// 声明一个结构体,在结构体中写入一个本类型的指针,做成链表
{
int num;
struct number *next;
};
struct number * INPUT( int n);//创建一个链表,将猴子的序号都存入链表中 关键是要做成循环链表 最后一个节点的下一个应该指向头节点
void SELECT(struct number *headptr, int n);// 利用循环等手段 进行筛选大王
int main()
{
int n;
printf("有:");
scanf_s("%d", &n);
while (getchar()!= '\n') // 保证了不正确的输入
continue;
printf("参加游戏\n");
SELECT(INPUT(n), n);// 调用相应函数 执行功能
getchar();
getchar();
return 0;
}
struct number * INPUT( int n)
{
struct number *headptr = NULL,*prev,*current;
for (int i = 1; i <= n;i++)//循环分别进行申请内存
{
current = (struct number*)malloc(sizeof(struct number));
if (current != NULL)
{
current->num = i;
if (headptr == NULL)// 第一节链节 要特别说明
{
headptr = current;
}
else// 之后的链节
{
prev->next = current;
}
current->next = NULL;// 这里一定要把最后一节的后面一个链节设为NULL
prev = current;// 一定要有这一步 要不在第一个链节创建完之后 会显示prev为NULL
}
}
current->next = headptr;// 使链表循环起来
return headptr;
}
void SELECT(struct number *headptr, int n)
{
struct number *prev = NULL, *current = NULL;
int count = 0;
current = headptr;
while (current->next != headptr)
{
current = current->next;//将current指向最后一个
}
while (current != current->next)
{
prev = current;//是prev指向current前一个 从而进行后面的一个一个向后退的步骤
current = current->next;
count++;// 计数器 也就是游戏规则 数4次的猴子出局
if (count % 4 == 0)
{
printf("%d被淘汰\n",current->num);
prev->next = current->next;
free(current);// 释放内存
current = prev;
}
}
printf("%d是大王\n", current->num);
free(current);
return;
}
用链表写的确比数组要简单很多,数组与链表的差别就是数组删除了一个元素其他元素要随之移动,而链表不用,只需要把链节连接起来就行,这样不仅在算法上简洁很多,而且操作上也简洁不少,唯一的不足就是在页面优化方面有一点不足,也就是scanf那里和“参加游戏”衔接的时候的问题(如果感兴趣可以复制下来,在自己的编译器上运行一下),希望下次能有所改进