N为1时,可以完美遍历并输出
N不为1时,在弹出1时,会输出错误数字,并且停止运行
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct List
{
int num;
struct List* next;
int n;
int N;
}List;
List* creatlist(int n, int N)
{
int i;
List* p, * r, * head;
p= r= head = (List*)malloc(sizeof(List));
head->next = p;
head->n = n;
head->N = N;
for (i = 1; i <= head->n; i++)
{
p->next = NULL;
p = (List*)malloc(sizeof(List));
p->num = i;
r->next = p;
r = p;
}
p->next = head->next;
return head;
}
List* input()
{
List* head;
int n, N;
printf("请输入演示总人数(<=10):\n");
scanf("%d", &n);
printf("请输入指定的数N(<=10):\n");
scanf("%d", &N);
head = creatlist(n, N);
return head;
}
void output(List* head)
{
List* q;
q = head->next;
printf("当前循环链表节点信息:");
for (int i = 0; i < head->n; i++)
{
printf("%d ", q->num);
q = q->next;
}
printf("\n");
}
void ysf(List* head, int n, int m)
{
int j = 0;
List* o, * u;
o = u = head;
if (m == 1)
{
getchar();
for (int i = 1; i <= n; i++)
{
u = o->next;
printf("弹出%d ", u->num);
o->next = u->next;
free(u);
head->n--;
output(head);
getchar();
}
}
else
{
getchar();
while (o->next != NULL)
{
++j;
o = o->next;
if (j == m - 1)
{
u = o->next;
printf("弹出%d ", u->num);
o->next = u->next;
free(u);
head->n--;
output(head);
j = 0;
getchar();
}
}
}
}
int main()
{
List* p;
p = input();
output(p);
ysf(p, p->n, p->N);
return 0;
}
在N不为1时,可以完整输出每个阶段的当前的约瑟夫环的结点信息
#include <stdio.h>
#include <stdlib.h>
#define ERROR 0
typedef struct Person {
int id, pwd; //数字域:id用来存储人的序号,pwd用来存储人的密码
struct Person* next; //指针域:指向下一个的指针
};
struct Person* head, * p, * pd;
/*创建单向循环链表*/
int createCLinkList(int n) {
int i;
head = (struct Person*)malloc(sizeof(struct Person)); //创建一个带头结点的链表
if (!head) return 0; //创建不成功,返回0
p = head;
for (i = 1; i < n; i++) {
pd = (struct Person*)malloc(sizeof(struct Person));
if (!pd) return 0;
p->next = pd;
p = pd;
}
p->next = head;
pd = head;
return 0;
}
/*输入密码*/
int inputPwd(int n) {
int a, b;
printf("请输入每个人的密码:");
for (a = 1;a <= n;a++) {
scanf_s("%d", &b);
pd->id = a;
pd->pwd = b;
pd = pd->next;
}
pd = p;
return b;
}
/*输出出列序号*/
int outList(int m, int n) {
int q, r;
for (q = 1;q <= n;q++) {
for (r = 1;r < m;r++) {
pd = pd->next;
}
p = pd->next;
m = p->pwd;//新的密码作为m值
printf("第%d号出列\n", p->id);
pd->next = p->next;
free(p);
}
return 0;
}
void menu() {
printf("\t\t************约瑟夫环杀人游戏************\n");
printf("\t\t 1.游戏开始\n");
printf("\t\t 2.继续游戏\n");
printf("\t\t 0.游戏结束\n");
}
/*约瑟夫环游戏菜单*/
int main() {
int m, n, a;//定义密码m,总人数n,游戏选项a
setvbuf(stdout, NULL, _IONBF, 0);//这是因为Eclipse环境下写C语言控制台需设置为无缓冲立即回显
menu();//杀人游戏菜单
do {
printf("约瑟夫环杀人游戏开始,请输入您的选择:");
scanf_s("%d", &a);
switch (a) {
case 1:
case 2: {
printf("输入总人数n:");
scanf_s("%d", &n);
createCLinkList(n);//创建循环链表
inputPwd(n);//输入密码
printf("数到m的人出列:");
scanf_s("%d", &m);
outList(m, n);//打印出列顺序
}
case 0:
printf("\t\t感谢使用!!!\n");
break;
default:
printf("\t输入错误!!!\n");
break;
}
} while (a != 0);
return 0;
}