约瑟夫圆桌问题
编号为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("请输入人数:\n"); 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\n"); 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("\n"); 52 }