什么是约瑟夫环
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。 从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。 例如:有10个人围成一圈进行此游戏,每个人编号为 1-10 。
怎样用链表知识解决约瑟夫环问题
首先,我们需要创建一个环形链表(必须要环形),每个单结构体里包含一个数据域(date)和一个指针域,数据域用来存放编号。然后我们要定义两个int* 型的变量,设为p,q,因为当报数报到某个数时,那个数就要被删除,在链表中也就是要删除对应的结构体,所以p,q也必须在一前一后的位置,一开始假设p在前并且p=head,q在后,q=head->next,并需要一个变量来计数设为i,i的初始值为1,当i每增加一位,p,q就要按指定的方向移动一位,当i=n(题中设定的数)时,我们就删除q所在的结构体也就是free(q),然后i又从1开始计数,以此类推
如果题中还需要还需要统计被删除的数据的话,那我们就还需要定义一个数组,假设为answer[100],同时还要定义一个用来遍历数组的变量j=0,当i每到达一次n时,就执行answer[j]=q->date,同时j++。
我们就以上面这个问题为例来编写代码,10个人,设定的数字为3
#include<stdio.h>
#include<stdlib.h>
typedef struct Circle{
int date;
struct Circle* next;
}circle;
int main()
{
int m,n,i,j;
int answer[100];
j=0;
m=10;
printf("输入设定的数:");
scanf("%d",&n);
circle *head,*p,*q,*tail;
head=(circle *)malloc(sizeof(circle));
head->next=NULL;
tail=head;
for(i=0;i<m;i++)
{
p=(circle *)malloc(sizeof(circle));
p->date=i+1;
tail->next=p;
p->next=head->next;
tail=p;
}
q=head->next;
p=tail;
i=1;
while(p!=q)
{
if(i==n)
{
answer[j]=q->date;
p->next=q->next;
free(q);
i=1;
q=p->next;
j++;
}
else
{
p=q;
q=q->next;
i++;
}
}
printf("胜利的数字为%d\n",p->date);
printf("被删除的数字依次为:");
for(i=0;i<j;i++)
{
printf("%d ",answer[i]);
}
return 0;
}
以上就是有关于约瑟夫环问题的解答了