约瑟夫环算法是: n 个人围成一圈,每个人都有一个互不相同的密码,该密码是一个整数值,选择一个人作为起点,然后顺时针从 1 到 k(k为起点人手中的密码值)数数。数到 k 的人退出圈子,然后从下一个人开始继续从 1 到 j (j为刚退出圈子的人的密码)数数,数到 j 的人退出圈子。重复上面的过程,直到剩下最后一个人。
/*约瑟夫环*/
#include <stdio.h>
#include <stdlib.h>
#define N 9 //环中人的个数
#define OVERFLOW 0
int KeyW[N]={4,7,5,9,3,2,6,1,8}; //每个人手中的密码
typedef struct LNode{ //定义循环链表
int keyword;
struct LNode * next;
}LNode,*LinkList;
void Joseph(LinkList p,int m,int x){ //x为总人数,m为删除的那个人手中的密码,起始的m为第一个人手中的密码
LinkList q;
int i;
if(x==0)return;
q=p;
m%=x;
if(m==0)m=x;
for(i=1;i<=m;++i){ //找到第m个人 p指向要删除的人的前一人 q指向要删除的人
p=q;
q=p->next;
}
p->next=q->next; //删除q
i=q->keyword; //得到下一个要删除的人的位置
printf("%d ",q->keyword);
free(q);
Joseph(p,i,x-1); //递归调用 总人数减1,输入新的密码
}
int main()
{
int i,m;
LinkList Lhead,p,q; //Lhead指向头,p指向尾指针,q指向新建指针
Lhead=(LinkList)malloc(sizeof(LNode));
if(!Lhead)return OVERFLOW;
Lhead->keyword=KeyW[0];
Lhead->next=NULL;
p=Lhead;
for(i=1;i<9;++i){
if(!(q=(LinkList)malloc(sizeof(LNode)))) return OVERFLOW;
q->keyword=KeyW[i]; //对q的keyword进行赋值
p->next=q; //将q赋给p的next
p=q; //p要指向尾部,将q赋给p
}
p->next=Lhead; //构造循环链表
printf("请输入第一次计数值m :\n");
scanf("%d",&m);
printf("输出的队列是:\n");
Joseph(p,m,N);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/d8214424247bb193a1bdd1a1305f4236.png)
------没有别人聪明,就请付出更多的努力------