赞
踩
约瑟夫环是有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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。