约瑟夫环问题(C语言)编序为1,2,...n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始人选一个整数作为报数上限m,从第一个人开始按顺时针方向从自1开始顺序报数,报

来源:学生作业帮助网 编辑:作业帮 时间:2024/05/12 02:23:29
约瑟夫环问题(C语言)编序为1,2,...n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始人选一个整数作为报数上限m,从第一个人开始按顺时针方向从自1开始顺序报数,报

约瑟夫环问题(C语言)编序为1,2,...n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始人选一个整数作为报数上限m,从第一个人开始按顺时针方向从自1开始顺序报数,报
约瑟夫环问题(C语言)
编序为1,2,...n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始人选一个整数作为报数上限m,从第一个人开始按顺时针方向从自1开始顺序报数,报到m时停止报数.报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始从1报数,如此下去,知道所有人全部出列为止,设计一个程序求出出列顺序.
采用单循环链表模拟此程序,按照出列的顺序印出各人的编号
测试数据:m的初值为20;n=7,7个人的密码依次为3,1,7,2,4,8,4.首先m的值为6(正确的出列顺序为6,1,4,7,2,3,5)
那位好人帮忙调试一下,感激不尽·!
代码如下:
#include
#include
typedef struct data
{
int num;
int val;
}typdata;
typedef struct node
{
typdata data;
struct node*next;
}listnode;
typedef listnode*linklist;
linklist head;
void main()
{
int n,i,b,m,j;
linklist head=(listnode*)malloc(sizeof(listnode));
listnode *p,*q;
printf("请输入总人数:");
scanf("%d",&n);
q=head;
for(j=1;jnext=(listnode*)malloc(sizeof(listnode));
q=q->next;
q->data.val=b;
q->data.num=j;
q->next=head->next;
}
printf("请输入初值:");
scanf("%d&quo

约瑟夫环问题(C语言)编序为1,2,...n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始人选一个整数作为报数上限m,从第一个人开始按顺时针方向从自1开始顺序报数,报
修改后的版本,解决初始m为1的情况.
#include
#include
typedef struct node{
int num;
int val;
struct node* next;
}listnode;
//两个结构体可以合并以减少程序复杂度
typedef listnode* linklist;
int main(){
int n,i,b,m,j;
linklist q=(listnode*)malloc(sizeof(listnode));
q->next=q;//即使只有一个元素,他也是个循环链表
listnode *p;
printf("请输入总人数:");
scanf("%d",&n);
p=q;
for(j=1;jval=b;
q->num=j;
if(j!=n){
q->next=(listnode*)malloc(sizeof(listnode));
q=q->next;
}
q->next=p;
}//循环结束后,q->next就是链表头
printf("last: num-%d val-%d\n",q->num,q->val);
printf("请输入初值: ");
scanf("%d",&m);
if(mnext,p就是目标.
printf("结果是:\n");
printf("出列顺序是: ");
//使用q为起始点
do{
i=0;//避免m减一后为零的问题
while(i!=m){
q=q->next;
i++;
}
p=q->next;
q->next=p->next;
printf(" %d",p->num);
m=p->val;//你少了这一步.
m=m-1;//提前使q停下,p=q->next,p就是目标.
free(p);
}while(q->next!=q);
printf(" %d\n",q->num);
free(q);
//free(head); //此时head也许已经被free掉
getchar();
getchar();
return(0);
}