(C语言)数据结构-线性表之队列实现约瑟夫环

题目描述:

约瑟夫环是有n个人围坐在圆桌周围,现在从某个位置i上的人开始报数,数到m的人就站出来,离开。下一个人,就是原来的第m+1个位置上的人,又从1开始报数,再次数到m的人站出来。依次重复下去,直到全部的人都站出来。按出列的先后又可以得到一个新的序列。例如,当n=8,m=4,i=1时,得到的新序列为:4、8、5、2、1、3、7、6。请编写程序用循环队列作为其储存结构模拟整个过程,并依次输出出列的各人的编号。

样例代码:

#include<stdio.h>
#include<stdlib.h>
#define FALSE 0
#define TRUE 1
typedef int QueueElementType;

//定义一个动态循环队列 
typedef struct{
	QueueElementType *element;	//元素空间 
	int front;	//头指针 
	int rear;	//尾指针 
}SeqQueue;

//初始化一个循环队列
void InitQueue(SeqQueue *Q){
	Q->front = Q->rear = 0;
} 

//循环队列入队操作,将元素x入队 
int EnterQueue(SeqQueue* Q, QueueElementType x){
	//尾指针+1追上头指针,标志队列已经满了 
	if((Q->rear+1) % MAXSIZE == Q->front){
		return FALSE;
	}
	//将元素x插入队尾
	Q->element[Q->rear] = x;
	//重新设置队尾指针
	Q->rear = (Q->rear + 1) % MAXSIZE;
	return TRUE;
} 

//循环队列出队操作,删除队列的队头元素,用x返回其值 
int DeleteQueue(SeqQueue* Q, QueueElementType *x){
	//队列不能为空 
	if(Q->front == Q->rear) return FALSE;
	//获取队头元素
	*x = Q->element[Q->front];
	//更改队头指针的指向
	Q->front = (Q->front + 1) % MAXSIZE;
	return TRUE; 
}

//打印队列内的元素 
int PrintQueue(SeqQueue *Q){
	//队列不能为空 
	if(Q->front == Q->rear) return FALSE;
	
	int i = 0;
	int front = Q->front;
	while(front < Q->rear){
		printf("%d ",Q->element[front]);
		front++;
	}
}
//计算约瑟夫环的结果 
void joseph(SeqQueue* Q,int n, int m, int i){
	int x,j,k;
	//通过循环生成一个从1到n的队列 
	for(j = 1; j <= n; j++){
		EnterQueue(Q,j);
	} 
	//通过删除和插入位移指针,让开始位置出现在第一个 
	for(k = 1; k < i; k++){
		DeleteQueue(Q,&x);
		EnterQueue(Q,x);
	} 
	//控制要输出的数据个数 (人数)
	for(j = 1; j <= n; j++) {
		//循环删除和插入用于移动指针指向
		for(k = 1; k < m; k++){
			DeleteQueue(Q,&x);
			EnterQueue(Q,x);
		}
		//当到m个时,取出其值并输出 
		DeleteQueue(Q,&x);
		printf("%d ",x);
	} 
}

int main(){
	int n;	//总人数 
	int m;	//数到第m个人 
	int i;	//开始位置 
	printf("请输入n m i对应的值:");
	scanf("%d%d%d",&n,&m,&i); 
	SeqQueue *Q;
	Q = (SeqQueue*)malloc(sizeof(SeqQueue));
	//开辟队列Q所存储的元素空间 
	Q->element = (QueueElementType*)malloc(sizeof(QueueElementType) * n);
	InitQueue(Q);
	joseph(Q,n,m,i);
	return 0;
}

样例输出:

在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孑然R

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值