要求说明:使用循环链表实现约瑟夫环。给定一组编号分别是4,7,5,9,3,2,6,1,8.初始值由用户输入,打印输出队列。
解:约瑟夫环算法是指;n个人围城一圈,每个人都有一个互不相同的密码,该密码是一个整数值,选择一个人作为起点,然后顺时针从1到k(k为起点人手中的密码值)数数。数到k的人退出圈子。然后从下一个人开始继续从1到j(j为刚退出圈子的人的密码)数数,数到j
的人退出圈子。重复直到剩下最后一个人。
//约瑟夫环
#include <stdio.h>
#define N 9
#define OVERFLOW 0
#define OK 1
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) // 实现使用循环链表实现约瑟夫算法,根据给定数获得一个数列
{
LinkList q;
int i;
if(x == 0)
return ;
q = p;
m %= x;
if(m == 0)
m = x;
for(i = 1; i <= m; i ++) // 找到下一个节点
{
p = q;
q = p -> next;
}
p -> next = q -> next;
i = q -> keyword;
printf("%d ",q -> keyword);
free(q);
Joseph(p,i,x-1); //递归调用
}
int main(int argc, char **argv)
{
int i,m;
LinkList 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++) //创建循环链表并赋值
{
q = (LinkList)malloc(sizeof(LNode));
if(!q)
return OVERFLOW;
q -> keyword = KeyW[i];
p -> next = q;
p = q;
}
p -> next = Lhead;
printf("please input the first record m:\n");
scanf("%d",&m);
printf("the output alignment is:\n");
Joseph(p,m,N);
return 0;
}
样例输入输出:
please input the first record m:
5
the output alignment is:
3 1 8 7 9 2 4 6 5