1.顺序结构
【最新写的代码版本】
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#define maxSize 100
void Joseph(int m, int n)
{
int a[maxSize];
int i, k, count;
for (i = 1; i <= n; ++i)
a[i] = i;
count = 0;
i = 1;//从第一个人开始报数
//当第n-1个人出队的时候退出循环,此时队列还剩下一个人未出队
while (count < n - 1)
{
k = 1;
while (k < m)
{
//下一个人报数,当报数为m时,找到报该数的人,然后退出循环
k++;
i = (i + 1) % (n + 1);
if (i == 0)
i = i + 1;
while (a[i] == 0)//若该人已经出队,则找到下一个还未出队的人
{
i = (i + 1) % (n + 1);
if (i == 0)
i = i + 1;
}
}
printf("%d ", a[i]);
a[i] = 0;//将此人出队
count++;//出队人数加一
//找到下一个未出队的人
i = (i + 1) % (n + 1);
if (i == 0)
i = i + 1;
while (a[i] == 0)
{
i = (i + 1) % (n + 1);
if (i == 0)
i = i + 1;
}
}
printf("%d ", a[i]);
}
int main()
{
Joseph(3, 13);
return 0;
}
【问题代码】
void Josehus(int j)//从第j个人开始报数
{
int a[N];
int count, k;
int i = j - 1;
for (k = 0; k < N; ++k)
a[k] = k + 1;
count = 0;
while (count < N)
{
k = 1;
while (k < M)
{
k++;
i = (i + 1) % N;
while (a[i] == 0)
i = (i + 1) % N;
}
printf("%d ", a[i]);
a[i] = 0;
i++;
count++;
}
}
【错误原因】
在i++这里出错,目的是找到下一个报数为1的人,但此处必须加循环,否则下一个报数为1的人就会变成已经出队的人的编号,此外,还需要有结束循环的条件,否则会变成死循环。
【正确代码】
#include <stdio.h>
#define N 13
#define M 3
void Josehus(int j)//从第j个人开始报数
{
int a[N];
int count, k;
int i = j - 1;
for (k = 0; k < N; ++k)
a[k] = k + 1;
count = 0;
while (1)
{
k = 1;
while (k < M)
{
i = (i + 1) % N;//默认第1个人已经报过数了
while (a[i] == 0)
i = (i + 1) % N;
k++;
}
printf("%d ", a[i]);
a[i] = 0;
count++;
if (count >= N)
break;
i = (i + 1) % N;//找到下一个报数为1的人,此处必须加循环,否则下一个报数为1的人就会变成已经出队的人的编号
while (a[i] == 0)
i = (i + 1) % N;
}
}
int main()
{
Josehus(1);
return 0;
}
【测试结果】
2.链表结构
【正确代码】
#include <stdio.h>
#include <stdlib.h>
#define N 13
#define M 3
typedef struct LNode
{
int data;
struct LNode* next;
}LNode;
void Josehus(int i)//从第j个人开始报数
{
LNode* L;
int count, k;
int j;
LNode*pre, *p;
LNode*s;
L = (LNode*)malloc(sizeof(LNode));
p = L;
for (j = 1; j <= N; ++j)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = j;
p->next = s;
p = s;
}
p->next = L;
//查找第i个人
for (p = L->next, pre = L; p != L; pre = p, p = p->next)
if (p->data == i)
break;
count = 0;
while (count < N)
{
k = 1;
while (k < M)
{
pre = p;
p = p->next;
if (p == L)
{
pre = p;
p = p->next;
}
k++;
}
printf("%d ", p->data);
pre->next = p->next;
free(p);//出队
p = pre->next;
if (p == L)
{
pre = p;
p = p->next;
}
count++;
}
}
int main()
{
Josehus(1);
return 0;
}