约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始从1报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
与下一个人继续报数,则下个是m的倍数的人出列,意思是一样的。
/*
author :lingling
date: 2011-10-05
description: 循环列表实现josephos
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
node* next;
}LinkList;
LinkList* create(int );
void JOSEPHUS(int ,int ,int ,LinkList*);
void main()
{
int n=9;
int m=5;
int k=1;
LinkList* p;
p = create(n);
/*for(int i=0;i<n;i++)
{
printf("%d->",p->data);
p= p->next;
}*/
JOSEPHUS(n,m,k,p); //共n个人,m的出列,从k开始报数
}
LinkList* create(int n)
{
LinkList* head,*p;
head= (LinkList*)malloc(sizeof(LinkList));
head->data=1;
head->next=head; //一个数据的循环链表,没有表头
p=head;
for (int i=1;i<n;i++) //不断插入进去,建立一个循环链表
{
LinkList* t=(LinkList*)malloc(sizeof(LinkList));
t->data=i+1;
p->next=t;
t->next=head;
p=p->next;
}
return head;
}
void JOSEPHUS(int n,int m,int k,LinkList* p)
{
LinkList* r,s;
while (k--) //把指针移到当前报数的人的编号
{
r=p;
p=p->next;
}
while (n>1)
{
for (int s=m-1;s>1;s--)
{
r = p;
p=p->next;
}
r->next=p->next;
printf("%d",p->data);
printf("\n");
free(p);
p=r->next;
r=p; //把r移动下一个人
p=p->next;
n--;
}
printf("最后一个出局的是%d",p->data);
printf("\n");
}
结果
现在对链表的操作熟悉了,但是这个的实现也是参考了答案,并且在调试的时候改正的。