再增加一种队列实现的代码#include<stdio.h>
#include<stdlib.h>
typedef struct QNode //节点结构
{
int data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct //队列的链表结构
{
QueuePtr front,rear; //队头队尾指针
}ListQueue;
void CreatQueue(ListQueue *Q,int n); //创建一个队列
void DealQueue(ListQueue *Q,int m); //按条件出队和入队操作
int main()
{
int m,n;
ListQueue Q;
Q.front=NULL;
Q.rear=NULL; //初始化队头队尾指针
printf("输入总人数n=");
scanf("%d",&n);
fflush(stdin);
printf("输入报数值m=");
scanf("%d",&m);
CreatQueue(&Q,n);
DealQueue(&Q,m);
return 0;
}
void CreatQueue(ListQueue *Q,int n)
{
int i;
QueuePtr q=NULL,p=NULL; //定义完指针后,记得初始化.否则把指针"栓"在NULL处
q=(QueuePtr)malloc(sizeof(QNode));
q->data=1;
q->next=NULL;
Q->front=q; //队头指针指向第一个节点
for(i=1;i<n;i++)
{
p=(QueuePtr)malloc(sizeof(QNode));
p->data=(i+1); //为每个人编号
q->next=p; //挂链
q=p;
}
p->next=NULL;
Q->rear=p; //队尾指针指向最后一个节点
}
void DealQueue(ListQueue *Q,int m)
{
QueuePtr q=NULL,p=NULL;
int k=0; //计数值
while(Q->front!=Q->rear) //当队头指针和队尾指针不同时指向同一个节点时,循环继续
{
q=Q->front; //指针q用于记录当前访问的节点
k++; //计数值加1
if(k==m)
{
printf("序号为 %d 的人出圈\n",Q->front->data); //如果当前节点的报数为m,则该节点出队
Q->front=q->next; //头指针指向当前节点的直接后继
free(q); //释放当前节点
k=0; //计数值重新开始
}
else
{
Q->rear->next=q; //当前访问的节点入队尾 (只不过是把不满足报数值的节点从队头变到了队尾)
Q->rear=q; //当前访问的节点作为队尾
Q->front=q->next; //队头指针指向当前节点的直接后继(即当前节点出队)
}
}
printf("序号为 %d 的人最后留下\n",Q->front->data);
}
|