数据结构 循环队列的实现与应用举例:报数问题

循环队列是一种常见的队列实现方式,各个数据元素依次存储,并设置两个指针,分别指向队头和队尾,在插入和删除数据时,队头指针和队尾指针会循环使用存储空间。应用队列可以解决报数问题。

报数问题:设有n个人站成一排,从左向右的编号分别为1~n, 现在从左向右报数“1,2,1,2,1,2….”,数到”1”的人出列,数到”2”的人站到队伍最右边。报数过程反复进行,直到n个人都出列为止。

分析:可以创建一个队列存储各个数据。左边相当于队头,右边相当于队尾。左边的人报数相当于从队列中取出队头元素并删除队头元素。站到队伍的最右边相当于在队尾插入一个数据。为实现1,2,1,2,1,2….报数,可以设置一个计数器变量count,count每次加1,count%2交替等于1和0,count%2等于1相当于报数1,count%2等于0相当于报数2。

此程序在VC++6.0 和 Dev-C++下编译通过。

#include "stdio.h"
#include "stdlib.h"
#define MAXQSIZE  100  //最大队列长度
typedef struct 
{
	int  *base;  // 动态分配存储空间
	int  front;     // 头指针,若队列不空,指向队列头元素
	int  rear;      // 尾指针,若队列不空,指向队列尾元素 的下一个位置
} SqQueue;

int InitQueue (SqQueue &Q) 
{
   // 构造一个空队列Q
	Q.base = (int *) malloc(MAXQSIZE*sizeof(int));
	if(!Q.base) 
		exit (-2);   // 存储分配失败
	Q.front = Q.rear = 0;
	return 1;
}
 
void DestroyQueue(SqQueue &Q)
{  //销毁队列
	free(Q.base);
	Q.base=NULL;
	Q.front=0;
	Q.rear=0;
}
 
int QueueEmpty(SqQueue Q)
{ //判断队列是否为空队列
	if(Q.front==Q.rear)
		return  1;
	else
		return  0;
}

int EnQueue(SqQueue &Q, int e)
{ /* 插入元素e为Q的新的队尾元素 */
	if((Q.rear+1)%MAXQSIZE==Q.front)
 		return  0;
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%MAXQSIZE;
	return  1;
}
 
int  DeQueue(SqQueue &Q, int &e)
{ /* 若队列不空,则删除Q的队头元素,用e返回其值,并返回1;否则返回0 */
	if(Q.front==Q.rear) /* 队列空 */
		return  0;
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%MAXQSIZE;
	return  1;
}
 
void baoshu(int n)
{
	SqQueue Q;
	int i,count=1,e;
	InitQueue(Q);
	for(i=1;i<=n;i++)
		EnQueue(Q, i);
	while(!QueueEmpty(Q))
	{
		DeQueue(Q,e);
		if(count%2==1)
			printf("%d ",e);
		else
			EnQueue(Q,e);
		count++;
	}
	printf("\n");
	DestroyQueue(Q);
}
 
int main()
{
	int n;
	printf("请输入人员数量:");
	scanf("%d",&n);
	baoshu(n);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值