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

链式队列是一种常见的队列实现方式,通过链表存储队列的各个数据元素,并设置两个指针,分别指向队头和队尾。应用队列可以解决报数问题。

报数问题:设有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"
typedef struct QNode 
{
	int data;
	struct QNode  *next;
} QNode, *QueuePtr;

typedef struct 
{
	QueuePtr front;  // 队头指针
	QueuePtr rear;   // 队尾指针
}LinkQueue;

int InitQueue(LinkQueue &Q)
{  //创建队列
	Q.front=(QueuePtr)malloc(sizeof(QNode));
	Q.rear=Q.front;
	Q.front->next=NULL;
	return 0;
}

int ClearQueue(LinkQueue &Q)
{  //清空队列
	QueuePtr p,q;
	Q.rear=Q.front;
	p=Q.front->next;
	Q.front->next=NULL;
	while(p)
	{
		q=p;
		p=p->next;
		free(q);
	}
	return  1;
}

void DestroyQueue(LinkQueue &Q)
{  //销毁队列
	ClearQueue(Q);
	free(Q.front);
	Q.front=NULL;
	Q.rear=NULL;
}

int QueueEmpty(LinkQueue Q)
{ //判断队列是否为空队列
	if(Q.front==Q.rear)
		return  1;
	else
		return  0;
}


int EnQueue(LinkQueue &Q,  int e) 
{  //向队尾插入一个数据元素
	QueuePtr p;
	p = (QueuePtr) malloc (sizeof (QNode));
	if (!p)  exit (-2);   //存储分配失败
	p->data = e;   p->next = NULL;
	Q.rear->next = p;    Q.rear = p;
	return 1;
}

int DeQueue (LinkQueue &Q, int &e) 
{ // 若队列不空,则删除Q的队头元素,
  //用 e 返回其值,并返回1;否则返回0
	QueuePtr p;
	if (Q.front == Q.rear)    return 0;
	p = Q.front->next;   e = p->data;
	Q.front->next = p->next;
	if (Q.rear == p)  Q.rear = Q.front;
	free (p);      
	return 1;
}

void baoshu(int n)
{
	LinkQueue 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、付费专栏及课程。

余额充值