使用单向循环表编制程序
设计一个程序求出约瑟夫环的出列顺序。约瑟夫环问题的一种描述是:编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一人开始重新从1报数,如此下去,直至所有人全部出列止。例如n=7,7个人的密码集资为:3,1,7,2,4,8,4,m的初值取6,则正确的出列顺序应为6,1,4,7,2,3,5。要求使用单向循环链表模拟出列过程。
#include <stdio.h>
#include <malloc.h>
typedef struct LNode{
int number;
int password;
struct LNode *next;
}linklist;
void insert(linklist *q,int n, linklist *head)
{
int i;
for( i=1; i<n; ++i ){
linklist *p;
p=(linklist*)malloc(sizeof(linklist));
scanf("%d%d",&p->number,&p->password);
q->next=p;
q=p;
}
q->next=head;
}
void Delete(linklist *head,int m)
{
linklist *q,*p;
q=head;
m--;
while(q->next!=q)//判断是否只有一个结点了
{
while( m-1 )//循环到要删除结点的前一个
{
q=q->next;
m--;
}
printf("%d\t",q->next->number);
m=q->next->password;
q->next=q->next->next;
}
printf("%d\n",q->number);
}
void main()
{
linklist *head,*q;
int m,n,i;
printf("The first password is :");
scanf("%d",&m);
printf("The total number is:");
scanf("%d",&n);
if(n>30||n<0)
printf("Error!");
head=(linklist*)malloc(sizeof(linklist));
head->next=NULL;
scanf("%d%d",&head->number,&head->password);
q=head;
insert(q,n,head);//改成在末尾追加插入,你的中间插入顺序就反了
Delete(head,m);
}