天之道

享受编程的乐趣。
posts - 118, comments - 7, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

使用循环链表解决约瑟夫问题

Posted on 2012-08-17 00:14 hoshelly 阅读(1030) 评论(0)  编辑 收藏 引用 所属分类: ProgrammingDS && Algorithm
假设有N个人决定选出一个领导人,方法如下:所有人排成一个圆圈,按顺序数数,每隔第M个人出局,此时他两边的人靠拢重新形成圆圈。问题是找出哪一个人将会是最后剩下的那个人。我们希望打印出所有人的出局顺序和最后选出的领导人是哪一位。

这个问题称为约瑟夫问题,可以利用链表解决。

代码如下:

  //约瑟夫问题
  
  #include<stdio.h>
  #include<stdlib.h>
  typedef struct node *link;
  struct node { int item; link next; }; //定义结点
  int main()
  {
     int i,N,M;
     printf("Input N and M: "); //N表示共有N个人,M表示每隔第M个人要出局
     scanf("%d%d",&N,&M);
     link t = (link)malloc(sizeof(node)); //新建结点t
     link x=t; 
     t->item = 1; t->next=t; //创建一个代表1号的单个节点的循环链表
     for(i=2;i<=N;i++)
     {
         x=(x->next= (link)malloc(sizeof(node)));//将2~N号按序插到之前创建的单个节点的循环链表中
         x->item=i; x->next=t;
     }
 
     while(x!= x->next) //如果不是最后一个节点,因为是循环链表,所以x!=x->next
     {
         for(i=1;i<M;i++) //则顺着链表向前遍历,数出M-1个元素
             x=x->next;
         printf("%d ",x->next->item);
         x->next = x->next->next; //删除第M个元素
         N--; //节点数减1
     }
     printf("\n%d\n",x->item); //最后打印出最后一个节点
     return 0;
 }

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理