链式队列是一种常见的队列实现方式,通过链表存储队列的各个数据元素,并设置两个指针,分别指向队头和队尾。应用队列可以解决报数问题。
报数问题:设有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;
}