【约瑟夫环】
N个人围成一圈,从第k个数开始报数,第M个被杀掉,重复这一步骤,直到所有的人都被杀掉。
【运用的方法】
本代码使用的是不带头结点的循环链表,相比于带头结点的链表,不带头结点的链表无非就是给头指针的数据域赋值而已。
找到开始计数的地方,到 M 个之后,删除第 M 个节点。然后继续计数并删除
【错误点】
在第一次试着编写这段代码的时候,找到第一个需要删除的节点,直接 free 掉,这样的话原本的循环链表就会断掉,所以在 free 之前,需要记住 前后两个节点,然后才能 free,再将链表重新连接起来,形成新的循环链表。
【代码实例】
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct Node{
int data;
struct Node *next;
}Lnode,*LinkList;
int main()
{
int n,k,m;
scanf("%d %d %d",&n,&k,&m);
if(n<0)
return 0;
else
{
LinkList H;
H=(Lnode *)malloc(sizeof(Lnode)); //第一个结点
if(H==NULL)
printf("no memory available!\n");
else
{
H->data=1; //第一个结点的值是1;
H->next=NULL;
Lnode *p; //p用来指向第一个结点,r用来添加节点
p=H;//p指向第一个结点
for(int i=2;i<=n;i++)
{
Lnode *r;
r=(Lnode *)malloc(sizeof(Lnode)); //申请空间,指向添加的结点
r->data=i;
r->next=NULL;
p->next=r;
p=r;
}
p->next=H;
}
Lnode *s;
Lnode *r;
s=H;
while(s->data!=k)
{
s=s->next;
}
int number=6;
while(number-1)
{
int num=1;
while(num!=m-1)
{
s=s->next;
num++;
}
r=s->next->next;
printf("%d ",s->next->data);
free(s->next);
s->next=r;
s=r;
number--;
}
printf("%d ",s->data);
}
return 0;
}