//约瑟夫环问题
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
struct data
{
int number;
struct data *next;
};
struct data *init_list();//建立一空的循环链表
struct data *insert_list(struct data *head, struct data *p); //插入元素(有序插入——从小到大)
struct data *crease_list(struct data *head,int n);//在空链表的基础上新建一非空循环链表
void print(struct data *head);
void print1(struct data *head);
void game(struct data *head);
//**********main函数********************
int main()
{
struct data *head;//头指针
int n; //n为人数
printf("\n请输入人数:");
scanf("%d",&n);
head=init_list(); //初始化链表
head=crease_list(head,n);
print(head); //打印
print1(head);
game(head);
return 0;
}
//*********建立一空的循环链表*********************
struct data *init_list()
{
struct data *head;
head=(struct data *)malloc(sizeof(struct data));
if(!head)
return 0;
head->next=head;
return head;
}
//***********在空链表的基础上新建一非空循环链表************
struct data *crease_list(struct data *head,int n)
{
struct data *p;
int i,k;
for(i=0;i<n;i++)
{
printf("请输入第%d个人的代号:",i+1);
scanf("%d",&k);
//这里必须的用k来过度,否则指针p会成为野指针
p=(struct data *)malloc(sizeof(struct data));
p->number=k;
head=insert_list(head,p); //插入元素
}
return head;
}
//*************插入元素(有序插入——从小到大)**********
struct data *insert_list(struct data *head, struct data *p)
{
struct data *p1,*p2;
p1=head;
p2=head->next;
if(head->next==head)
{
p->next=head;
head->next=p;
}
else
{
while( (p->number > p2->number) && (p2->next != head) )
{
p1=p2;
p2=p2 -> next;
}
if(p->number <= p2->number)
{
p->next=p2;
p1->next=p;
}
else
{
p->next=head;
p2->next=p;
}
}
return head;
}
//***************游戏开始******************
void game(struct data *head)
{
int i,j,m; //m为所报的数
struct data *p1,*p2;
p1=head;
p2=head->next;
printf("*******Game start!!!*******\n");
printf("Please Input m:");
scanf("%d",&m);
while( head->next != head )
{
for(i=0;i<m-1;i++)
{
p1=p2;
p2=p2->next;
//之前就因为下面的这个if语句没有加进去,困扰了好长一段时间
//注意这个if语句加在循环语句中的目的:避免头指针充当一次移位
if(p2==head)
{
p1=p2;
p2=p2->next;
}
}
printf("%4d",p2->number);
p1->next=p2->next; //p2脱链
free(p2); //释放p2
p2=p1->next;
if(p2==head) //跳过头结点
{
p1=p2;
p2=p2->next;
}
}//while
printf("\n");
free(head);
}
//****************打印函数****************
void print(struct data *head)
{
struct data *p;
if(head->next==head)
{
printf("\nThe list is null!!!\n");
}
else
{
for(p=head->next;p!=head;p=p->next)
{
printf("%4d",p->number);
}
}
printf("\n");
}
//**********循环打印************
void print1(struct data *head)
{
int i;
struct data *p;
p=head->next->next->next;
for(i=0;i<10;i++)
{
printf("%4d",p->number);
p=p->next;
if(p==head)
{
p=p->next;
}
}
printf("\n");
}