问题描述:设有n个人围坐在圆桌周围,现从某个位置m(1<=m<=n)上的人开始报数,报到k的人就站出来。下一个人,即原来的第k+1位置上的人又从1开始报数,再报数到k的人站出来。以此重复下去,直到所有的人都站出来为止。
#include<stdio.h>
#include<stdlib.h>
typedef int Elemtype;
/*数据类型定义*/
typedef struct Cnode{
Elemtype data;
struct Cnode *next;
}CNode;
CNode *joseph; /*定义一个全局变量*/
int Create_clist(CNode *clist,int n);
int Joseph(CNode *clist,int m,int n,int k);
int Create_clist(CNode *clist,int n) /*创建循环链表*/
{
CNode *p,*q;
int i;
clist = NULL;
for( i=n ; i>0 ;i--)
{
p=(CNode *)malloc(sizeof(CNode));
if( p ==NULL)
return -1;/*存储分配失败*/
p->data = i;
p->next = clist;
clist = p;
if( i==n )
q=p; /*用q指向链表的最后一个结点*/
}
q->next = clist;/*把链表的最后一个结点的指针域指向第一个结点,形成循环链表*/
joseph=clist; /*使得指针的头结点给全局变量*/
return 1;
}
int Joseph(CNode *clist,int m,int n,int k)
{
int i;
CNode *p,*q;
if(m>n ||!Create_clist(clist,n) )
return -1; /*创建链表失败*/
p=joseph; /*p指向创建好的链表*/
for( i=1 ; i<m ;i++)
p=p->next; /*p指向m位置的结点*/
while(p){
for(i=1 ;i<k-1 ; i++)
p=p->next; /*找出第k-1个结点*/
q = p->next;
printf("%3d",q->data); /*输出这个结点*/
if(p->next == p )
p=NULL; /*删除最后一个节点*/
else {
p->next = q->next;
p = p->next;
free(q);
}
}
clist = NULL;
return 1;
}
int main(void)
{
int m,n,k;
CNode *clist;
clist = NULL;
printf("请输入坐在圆桌周围的人数n:");
scanf("%d",&n);
printf("请输入第一次开始报道数的人的位置m:");
scanf("%d",&m);
printf("你希望报道的第几个人出列k?");
scanf("%d",&k);
Create_clist(clist,n);
printf("出列顺序如下:\n");
Joseph(clist,m,n,k);
printf("\n");
return 0;
}