首页 > 技术文章 > 约瑟夫环(数组、链表)

xirfly 2019-12-13 16:29 原文

约瑟夫环(数组)

设有SIZE=30个人围坐一圈,从某个人开始报数,数到N=7的人出列,接着往下从下一个人开始重新报数,数到N=7的人又出列,直到所有的人出列为止。输出出列的顺序。

实验代码

#include<stdio.h>
#define SIZE 30
int main()
{
	int index=0;
	int step=1;
	int count=0;
	
	int outs[SIZE]={0};
	int flag[SIZE]={0};
	
	index=0,step=1,count=0;
	while(count < SIZE)
	{
		if(step==7)
		{
			outs[count] = index+1;
			count++;
			step = 0;
			flag[index] = 1;
		}
		
		index = (++index)%SIZE;  //求余,循环遍历
		if(flag[index]==0)
		{
			step++;
		}
	}
	
	for(count=0;count<SIZE;count++)
	{
		printf("%d\n",outs[count]);
	}
	
	return 0;
}

Joseph 环(链表)

*问题描述:编号是 1,2,……,n 的 n 个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。一开始任选一个正整数作为报数上限值 m,从第一个仍开始顺时针方向自 1 开始顺序报数,报到 m 时停止报数。报 m 的人出列,将他的密码作为新的 m 值,从他在顺时针方向的下一个人开始重新从 1 报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序。
*要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。
*测试数据:m 的初值为 20,n=7 ,7 个人的密码依次为 3,1,7,2,4,7,4,首先 m=6,则正确的输出是什么?

实验代码

#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
	int key;//每个人持有的密码
	int num;//这个人的编号
	struct Node* next;//指向下一个节点
}Link;
Link* InitList()//创建一个空的链表
{
	Link* L;
	L = (Link*)malloc(sizeof(Link));
	L->key = 0;
	L->num = 0;
	L->next = L;
	return L;
}
Link* Creater(Link* L, int n)//初始化链表
{
	Link* p, * q;
	int i;
	q = L;
	for (i = 1; i <= n; i++)		//构建链表 
	{
		p = (Node*)malloc(sizeof(Node));
		printf("第%d个人的密码:", i);
		scanf("%d", &p->key);   //成员密码存放到key中 
		p->num = i;				//编号存放到num中 
		L->next = p;			//将p的地址赋值给L的指针域 
		L = p;                  //将p的值赋值给L
	}
	L->next = q->next;		//构建为环状 
	free(q);
	return L;
}
void Output(Link* L, int n, int m)
{
	Link* p, * q;
	int i, j;
	p = L;

	printf("\n结果序列为:");
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j < m; j++)
			p = p->next;        //p指到目的结点前一个结点
		q = p->next;        //q指向目的结点
		m = q->key;

		printf("%d ", q->num);

		p->next = q->next;       //此两步是为了释放目的结点,即删除
		free(q);
	}
}
int main()
{
	Link* L, * S;
	int n, m;

	L = InitList();            //构造出一个只有头结点的空链表

	printf("请先输入总人数:");
	scanf("%d", &n);         //总共的人数n 

	printf("请确定开始时的报数上限值:");
	scanf("%d", &m);        //初始密码为m

	S = Creater(L, n);//建立好一个约瑟夫环
	Output(S, n, m);
}

推荐阅读