您的位置:首页 > 其它

约瑟夫问题(丢手帕)的实现

2016-02-21 18:50 197 查看
约瑟夫问题(或称丢手帕问题)是指n个人围成一圈,从第一个人开始数1,数到第m个人数m则将m位置删除,继续接着从1数,数到m则将m位置删除。如此循环,每次删除一个。这个问题的来源据说是39个传教士和2个朋友困在一个山洞中,传教士宁愿死也不愿被敌人抓到,故而决定大家一个一个自杀,这样可以避免同时自杀可能某些传教士后悔。但2朋友是不想死的,于是其中一个人将他俩的位置安排在16和31,这样最终避免了两个人的死亡。

这个问题从以下方向突破:

1.n个人围成1圈。

2.每次循环数m个数。

这样可以通过循环链表来实现遍历圈内的元素进行数数,可以通不过从1不断累加至m......2m......3m......每当数至m的整数倍时即可进行删除操作。程序的框架也就是初始化链表---->循环遍历链表---->每每遍历至m的整数倍时执行删除操作和输出删除的序号。(程序是参考自网络并且自己验证过)。

#include <stdio.h>
#include <stdlib.h>

#define  TRUE 1
#define  FALSE 0
#define  ERROR -1

typedef int ElemType;
typedef struct Node{
ElemType data;
struct Node *next;
}Node;

typedef struct Node* LinkList;

int InitializeList(LinkList L);
int TraverseList(LinkList L);

int main(int argc,char *argv[])
{
printf("*******Main*******\n");
Node L;
L.next=&L;
InitializeList(&L);
TraverseList(&L);
system("pause");
exit(0);
}

int InitializeList(LinkList L)
{
LinkList p,current;
current=L;
int i;
for (i=0;i<41;i++)
{
p=(LinkList)malloc(sizeof(Node));
p->data=i+1;
p->next=L;
current->next=p;
current=p;
}
return TRUE;
}

int TraverseList(LinkList L)
{
LinkList p=L,temp;
int i=1;
while (p->next!=p)  //仅剩自己一个结点
{
if (i%3==0)
{
printf("%d",p->next->data);
temp=p->next;
p->next=p->next->next;
free(temp);
}
else{
p=p->next;
}
i++;
if (p->next==L)
{
p->next=L->next;
}
}
printf("%d",p->data);
free(p);
return TRUE;
}
在验证程序的时候,跳过L节点是在if语句中应该用"=="判断下一个结点是否是L结点时我使用了"="结果自然得不到正确结果。总之,程序出错时还需要去跟代码,找错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: