约瑟夫圆桌问题

编号为1,2,3,…,n的n个人按顺序针方向围坐一张圆桌旁,每个人手中持有

一个密码(正整数)。首先输入一个正整数作为报数上限值m,然后,从第一个人开始按顺序针方向自1开始顺序报数,报到m的人离开桌子,并将他手中的密码作为新的m值,从顺序针方向的下一个就坐在桌旁的人开始重新从1报数,如此下去,直至所有人全部离开桌旁为止。

算法思想:

用单循环链表来解决这一问题,实现的方法首先要定义链表结点,单循环链表的结点结构与一般单链表的结点结构完全相同,只是数据域用一个整数来表示;然后将它们组成一个单循环链表。接下来从位置为1的结点开始数,数到第m-1个结点,就将下一个结点从循环链表中删除,然后再从删去结点的下一个结点开始报数,如此下去,直到所有的人离开桌子。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 typedef struct node
 4 {
 5     int data;
 6     struct node *next;
 7 } listNode;    
 8 typedef listNode *linklist;
 9 main()
10 {
11     int i,m,n;
12     linklist head,s,r,p;
13     head=(linklist)malloc(sizeof(listNode));
14     head->data=1;
15     head->next=NULL;
16     r=head;
17     printf("请输入人数:
");
18     scanf("%d",&n);
19     for(i=2;i<=n;i++)
20     {
21         s=(linklist)malloc(sizeof(listNode));
22         s->data=i;
23         r->next=s;
24         r=s;
25     }
26     r->next=head;
27     p=head;
28     printf("请输入报数上限值m
");
29     scanf("%d",&m);
30     while(p)
31     {
32         for(i=1;i<=m-1;i++)
33         {
34             r=p;
35             p=p->next;
36         }
37         m=p->data;
38         printf("%d ",m);
39         if(p->next!=r)
40         {
41         r->next=p->next;
42         free(p);
43         p=r->next;
44         }
45         else
46         {
47             p=NULL;
48             printf("%d",r->data);
49         }
50     }
51     printf("
");
52 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6096132.html