使用单向循环链表,完成约瑟夫环问题
情景描述:n个人围成一圈,从某人开始报数1,2,3...m,数到m的人出圈,然后从出圈的下一个人(m+1)开始重复此过程,直到全部人出圈,于是得到一个出圈人员的新序列
函数有参考约瑟夫环(c语言程序完整版)_理工科的杜小甫的博客-CSDN博客_c语言约瑟夫环
本人增加了注释,更改输入人数,起始位置,间隔数为手动输入。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Node
{
int num; //结点数据域
struct Node *next; //结点指针域
}LinkList;
LinkList *creat(int n) //创建有n个结点的循环单链表
{
int i = 1;
LinkList *p,*q,*head;
p = (LinkList*)malloc(sizeof(LinkList));
p->num = i;
head = p;
for(i = 2;i<=n;i++)
{
q = (LinkList*)malloc(sizeof(LinkList));
q->num = i; //数据域赋值
p->next = q;
p = q;
}
p->next = head; //形成循环
return head; //返回头结点
}
void fun(LinkList *L,int k,int m)
{
int i,j;
LinkList *p,*q,*s;
p = L;
for(i = 1;i<k;i++) //将p指针放在要开始的地方
{
q = p;
p = p->next;
}
while(p->next!=p) //直到链表只有一个结点
{
for(j = 1;j<m;j++)
{
q=p;
p = p->next;
}
printf("%d\t",p->num);
s = p; //标记排到的结点
q->next = p->next;
p = p->next;
free(s); //释放标记到的结点
}
printf("%d\n",p->num); //输出最后一个结点的数据
}
void main()
{
LinkList *L;
int n,k,m;
printf("请输入基数n:\n");
scanf("%d",&n);
L=creat(n);
printf("请输入从哪个数字开始k:\n");
scanf("%d",&k);
printf("请输入间隔数m:\n");
scanf("%d",&m);
printf("约瑟夫环为:\n");
fun(L,k,m);
}