阿特图

无忧无争,潜心成魔.

经典算法问题之约瑟夫问题

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


  这里我们用循环链表来实现

*/

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


struct Node;//声明节点
typedef struct Node *PtrToNode;
typedef PtrToNode Position;
typedef PtrToNode Head;
typedef PtrToNode List;


//节点定义
struct Node{
 int No;//编号
 char name[10];//名称
 Position next;
};

 


/*建立链表*/
List createLink(int num)
{

 Head head = NULL,p = NULL,q = NULL;
 int i=1;
 char name[10];

 head = (Position)malloc(sizeof(struct Node));//建立头节点 
 head->No = 1;
 p=head;

 printf("请输入第1个人名称: \n");
 scanf("%s",name);
 strcpy(p->name,name);

 

 for(i=2;i<=num;i++)
 {
  q = (Position)malloc(sizeof(struct Node));
  if(q==0)return 0;

  p->next = q;
  p = q;
  p->No = i;

  printf("请输入第%d个人名称: \n",i);
  scanf("%s",&name);
  strcpy(p->name,name);
 }
 p->next = head;//让最后一个节点的指针指回头结点
 return head;//将头节点返回
}


/*建立约瑟夫环,num表示人数,n表示每n个删掉一个*/
void jose(Position p,int num,int n)
{
 int i,j = 0;
 Position q = NULL;
 for(i = 1;i<=num;i++)
 {
  
   //找到要被删除节点的上一个节点保存在p中
   for(j=1;j<n-1;j++)
   {
    p = p->next;
   }

   q = p->next;//将需要删除的节点暂时保存在q中,此时p表示要删除节点的上一个节点
   
   //将p->next(要删除的节点)从链表中删除
   p->next = q->next;
   p = p->next;
   printf("第%3d个出圈的是:%3d,name is %s\n",i,q->No,q->name);
   free(q);//释放所占内存空间
  
  printf("\n");

 }
}

 

 

 

int main()
{
 Head head = createLink(15);
 jose(head,15,4);
 system("PAUSE");
 
return 1;

}

 

 

 

//执行效果如下图所示:

 

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gotosola/article/details/7416041
个人分类: Data Struct
想对作者说点什么? 我来说一句

数据结构实验之约瑟夫

2010年07月16日 78KB 下载

数据结构程序之约瑟夫循环

2010年11月23日 4KB 下载

C++版数据结构之约瑟夫

2009年04月09日 2KB 下载

C++数据结构之约瑟夫环.

2013年03月26日 104KB 下载

没有更多推荐了,返回首页

不良信息举报

经典算法问题之约瑟夫问题

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭