手动构造循环队列实现约瑟夫环

约瑟夫环问题

问题重述

已知有n个人他们彼此都有编号且互不相同,他们围坐在一起。从第k个人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

第一行由键盘输入一个n,接下来的一行共n个互不相同的数由空格间隔,第三行输入k和m空格间隔要求程序给出他们的出列顺序;

代码实现
#include<stdio.h>
#include<stdlib.h> 
int MAXQSIZE;     		//循环队列长度为(MAXQSIZE-1)
typedef struct{         //定义队列 
	int*base;
	int front;
	int rear;
}SqQueue;
void init(SqQueue&L)    //创建循环队列并初始化 
{
	L.base=(int*)malloc(MAXQSIZE*sizeof(int));
	if(!L.base)         //若创建失败退出程序 
		exit(0);
	L.front=L.rear=0;   //初始化队列赋空 
}
void input(SqQueue&L)   //初始化循环队列  赋初值 
{
	int a,b;
	while(1)            //循环输入当按下回车时结束 
	{
		scanf("%d",&a);
		L.base[L.rear]=a;
		L.rear++;
		b=(MAXQSIZE+L.rear-L.front)%MAXQSIZE;
		if(getchar()=='\n'||b==MAXQSIZE-1)  //判断是否按下回车以及队是否已满 
		break;
	}
}
int DeQueue(SqQueue&L) //出队函数 并返回值 
{
	int e;
	if(L.front==L.rear)  //判断队列是否为空若为空提示有关信息 
		printf("队列已为空\n");
	else                 //不为空队头出队e记录 
	{
		e=L.base[L.front];
		L.base[L.front]=0;
		L.front++;
		if(L.front>=MAXQSIZE)
			L.front%=MAXQSIZE;
	} 
	return e;
}
void EnQueue(SqQueue&L,int e) //入队函数 
{
	if((MAXQSIZE+L.rear-L.front)%MAXQSIZE==MAXQSIZE-1)
		printf("队列已满");   //判断队列是否已满若满提示有关信息 
	else                      //未满在队尾入队 
	{
		L.base[L.rear]=e;
		L.rear++;
		if(L.rear>=MAXQSIZE)
			L.rear%=MAXQSIZE;
	}
}
void output(SqQueue&L,int start,int distance)//总功能函数 
{                //接收队列起始位置与间隔调用函数输出结果 
	int count=1,i,e;
	while(L.front!=start-1)  //调用出队入队函数将用户输入位置变为队头 
	{
		e=DeQueue(L);
		EnQueue(L,e);
	}
	while(L.front != L.rear) //当队列不为空时循环输出约瑟夫环的序列 
	{
	  if(count!=distance)    //count计算用户输入的间隔 
	  {                      //不满足到队尾 
	  	e=DeQueue(L);         
		EnQueue(L,e);
		count++;
	  }	
	  else                   //满足则出队
	  {
	  	e=DeQueue(L);
	  	printf("%d ",e);
	  	count=1;
	  }	
	} 
	printf("\n");
}
int main()                 //主函数 
{
	scanf("%d",&MAXQSIZE); //输入序列长度 
	MAXQSIZE+=1; 		   //循环队列空要空一个空间所以多开一个长度 
	SqQueue L;              
    int start,distance;
	init(L);               //调用初始化函数 
	input(L);              //输入循环队列的值 
	scanf("%d%d",&start,&distance);   
	output(L,start,distance);
	return 0;
}
测试输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值