题目:约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 结果+1即为原问题的解。
#include <stdio.h>
struct node{
int data;
struct node *next;
};
//创建链表
struct node *link(int n)
{
struct node *head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
struct node* prear=head;//尾部指针
int i=1;
while(i<=n)
{
struct node *newnode=malloc(sizeof(struct node));
newnode->data=i++;
prear->next=newnode;//新节点插入链表中
prear=newnode;//更新尾部指针指向
}
prear->next=head->next;
free(head);
return prear->next;
}
int main()
{
int n,m,k,i;
printf("请输入人数n和间隔数字m:");
scanf("%d %d",&n,&m);
printf("\n输入开始报数的编号k:");
scanf("%d",&k);
struct node* p=link(n);
struct node* temp;
for(i=1;i<k;i++)p=p->next;//p指向第k个节点
while(p->next!=p) //当p不是空表的时候进行循环
{
for(i=1;i<m;i++)
{
temp=p;
p=p->next;
} //temp指向m-1个节点,p指向第m个节点
printf("%d ",p->data);//输出第m个节点,即被删掉的节点
//删除指定的节点,p指向新的出发点
temp->next=p->next;
p=temp->next;
free(temp);
}
printf("\n最后剩下:%d",p->data);
free(p);
return 0;
}