1. 程式人生 > >迴圈佇列之約瑟夫環

迴圈佇列之約瑟夫環

此問題的要求為:n個人圍坐一圈,從第一個人開始數,每數到k,這個人就出列,圈中的下一個人重新從1開始計數,直到剩餘人數不足k人

下面我畫圖來加深理解(抱歉目前還不會用電腦繪製動畫,只好手動繪製,比較粗糙,之後有時間我改進下!!(看起來像個效果器上面的一堆旋鈕哈哈哈

在這裡插入圖片描述

下面附上完整程式碼:

//約瑟夫環 
#include<stdio.h>
#include<stdlib.h>

typedef struct 
{
	int *data;
	int front,rear;
	int queuesize;
	int length;
}Queue;

void Init (Queue *Q)                  //構造一個佇列 
{
	Q->queuesize = 100;
	Q->data = (int *)malloc(Q->queuesize*sizeof(int));
	Q->front = Q->rear = 0;
	Q->length = 0;
}

void build (Queue *Q)                   //為佇列賦值 
{
	int i,n;
	printf("請輸入環中元素個數:\n");
	scanf("%d",&n);
	printf("請輸入元素:\n");
	for(i=0;i<n;i++)
	{
		scanf("%d",&Q->data[Q->rear]); 
		Q->length++;
		Q->rear = (Q->rear+1)%100;
	}
	/*for(i=0;i<n;i++)								//檢驗是否入隊成功 
	{
		printf("%d ",Q->data[Q->front]);
		Q->front = (Q->front+1)%100;
	}*/ 
	printf("\n------%d-----\n",Q->length);          //輸出佇列長度 
	Q->front = 0;
}

void EnQue (Queue *Q,int e)                        //入隊 
{
	if((Q->rear+1)%100 != Q->front)
	{
			Q->data[Q->rear] = e;
			Q->rear = (Q->rear+1)%100;
	}
}

void OutQue(Queue *Q)                              //出隊 
{
	if(Q->rear != Q->front)
	{
		Q->front = (Q->front+1)%100;
	}
}

void display(Queue *Q)                        //輸出(也包含出隊的功能) 
{
	if(Q->rear != Q->front)
	{
		printf("%d ",Q->data[Q->front]);
		Q->front = (Q->front+1)%100;
	}
}

void yuesefu(Queue *Q)
{
	int  k=1,e;
	while(Q->rear!=Q->front&&Q->length>=3)
	{
		e = Q->data[Q->front];
		if(k == 3)
		{
			display(Q);
			k = 1;
			Q->length--;
		}
		else
		{
			OutQue(Q);								//就是讓這個不出列的數先從頭出隊,再從隊尾入隊 
			EnQue(Q,e);
			k++;
		}
	}
}


int main()
{
	Queue Q;
	Init(&Q);
	build(&Q);
	yuesefu(&Q);
	
	return 0;
}