C语言求解约瑟夫问题

约瑟夫问题简述著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数到3,循环直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,于是,他将朋友与自己安排在第16个与第31个位置,于是最后自杀只剩下他们两人,便逃过了这场死亡游戏。

josephus.c

#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);
int TraverseList(LinkList L);

/*使用循环链表,求解约瑟夫问题*/
int main(int argc,char *argv[])
{
  printf("********Main*********************************\n");
 
   Node L;
   L.next=&L;
   InitializeList(&L); //初始化循环链表
   TraverseList(&L); //求解约瑟夫问题
   exit(0);
}

int InitializeList(LinkList L)
{
  LinkList p,current;
  current=L;
  int i;
  for(i=0;i<41;i++) //初始化41个结点
    {
      p=(LinkList)malloc(sizeof(Node));
      p->data=i+1;
      p->next=L;
      current->next=p;
      current=p;
    }
}

int TraverseList(LinkList L)
{
  LinkList p=L,tmp;
  int i=1;
  while(p->next!=p) //自己指向了自己,说明循环链表除了空的头结点外,就只剩一个结点了。
    {
		if(i%3==0) //数到3,这个人就要被咔嚓掉了
		{
		  printf("%d,",p->next->data);
		  tmp=p->next;	
		  p->next=p->next->next; 
		  free(tmp);
		}
		else 
		{
		  p=p->next;
		}
		  i++;
		if(p->next==L) //循环链表的头,是个空节点,所以要跳过它。
		{
		  p->next=L->next;
		}
    }
  printf("%d,\n",p->data); //把最后一个结点的值输出,即最后一个幸存者
  free(p);
  return TRUE;
}
相关文章
相关标签/搜索