/*
2012
一群人(排列序号从1到N,N可设定)围成一圈,
按一定规则出列,剩余的人仍然围成一圈.出列规则
是顺着1到N的方向对圈内的人从1到C计数(C可设定),
圈内计数为C的人出列,剩余的人重新计数,按上述规
则,让圈内所有的人出列.请编程顺序输出出列编号的
序列
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node * listNode;
struct node
{
int data;
struct node *next;
};
listNode createCircleList(listNode head,int n)
{
//需要临时生成的临时结点指针,指向循环链表最后一个结点的指针
int i=1;
//s是临时结点,p是记录指针,始终指向最后一个结点,head的是传入的头结点指针,头结点不存数据,但是有头结点的更容易后面的操作
listNode s=NULL;
listNode p=head;
while(i<=n){//用的是尾插法
s=(listNode)malloc(sizeof(struct node));
s->data=i;
i++;
p->next=s;
p=p->next;
}
p->next=head->next;//这句是建立循环的关键,不要漏了
free(head);//建好循环列表之后,释放掉没有数据的头结点
return p;//返回的循环链表的最后一个结点,因为这样数数的时候,1就可以代表第一个结点;在主函数中有用
}
int main()
{
int n,m;
listNode p=NULL;
listNode temp=NULL;
listNode head=NULL;
head=(listNode)malloc(sizeof(struct node));
printf("请输入要总个数和要分割的位数,用空格分开:\n");
scanf("%d%d",&n,&m);
if(n<m){
printf("不符合输入条件\n");
return 0;
}
p=createCircleList(head,n);
int i;
while(p!=p->next){//循环链表结束的条件是自己指向自己,这样就剩一个结点
for(i=1;i<m;i++){//找到要删除的结点的前一个结点位置,所以没有等号
p=p->next;
}
temp=p->next;
printf("%d->",temp->data);
p->next=temp->next;
free(temp);
}
printf("%d",p->data);//打印出剩下的最后一个结点
return 0;
}
12约瑟夫环
最新推荐文章于 2023-04-05 15:21:16 发布