1、编写函数,实现链式队列的基本操作;
2、编写函数,实现循环队列的基本操作。
创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素
typedef struct QNode { /* 结点类型*/
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct { /* 链队列类型*/
QueuePtr front; /* 队头指针*/
QueuePtr rear; /* 队尾指针*/
} LinkQueue;
Status InitQueue (LinkQueue *Q) {
/* 构造一个空队列Q*/
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if (!p) exit (OVERFLOW);
/*存储分配失败*/
p->next = NULL;
Q->front=p;
Q->rear=p;
return OK;
}
链队队列中,当有新的数据元素入队,只需进行以下 3 步操作:
- 将该数据元素用节点包裹,例如新节点名称为 newnode;
- 与 rear 指针指向的节点建立逻辑关系,即执行 rear->next=newnode;
- 最后移动 rear 指针指向该新节点,即 rear=newnode;
由此,新节点就入队成功了。
例如,在图 1 的基础上,我们依次将 {1,2,3}
依次入队,各个数据元素入队的过程如图 2 所示:
Status CreateQueue (LinkQueue *Q,int n) {
/* 创建n个元素的队列Q*/
QueuePtr newnode;
int i;
for (i=1;i<=n;i++)
{newnode=(QueuePtr)malloc(sizeof(QNode));
if (!newnode) exit (OVERFLOW);
/*存储分配失败*/
scanf("%d",&newnode->data);
newnode->next = NULL;
Q->rear->next = newnode;
Q->rear = newnode;
}
return OK;
}
//入列操作
Status EnQueue (LinkQueue *Q,QElemType e) {
QueuePtr newnode;//创建一个新的结点
newnode=(QueuePtr)malloc(sizeof(QNode));//给结点分配一个空间
newnode->data=e;
newnode->next=NULL;
Q->rear->next=newnode;//尾结点指向新结点
Q->rear=newnode;//尾结点变成最后一个结点
return OK;
}
当链式队列中,有数据元素需要出队时,按照 "先进先出" 的原则,只需将存储该数据的节点以及它之前入队的元素节点按照原则依次出队即可。
链式队列中队头元素出队,需要做以下 3 步操作:
- 通过 top 指针直接找到队头节点,创建一个新指针 p 指向此即将出队的节点;
- 将 p 节点(即要出队的队头节点)从链表中摘除;
- 释放节点 p,回收其所占的内存空间;
例如,在图 2b) 的基础上,我们将元素 1 和 2 出队,则操作过程如图 3 所示:
Status DeQueue (LinkQueue *Q,QElemType *e) {
/* 若队列不空,则删除Q的队头元素,
用 e 返回其值,并返回OK;否则返回ERROR*/
/*请完成函数*/
QueuePtr p;//p用来存放删除的元素
if(Q->rear==Q->front)//即队列为空
return ERROR;
p=Q->front->next;//p指向表头元素的下一个元素 ,即要删除的结点
*e=p->data;//存放值到p数据域
Q->front->next=p->next;//p指向要删除结点的下一个结点
if(Q->rear==p) Q->rear=Q->front;
return OK;
free(p);
}
//队列的遍历
Status QueueTraverse(LinkQueue Q)
{
QueuePtr p;
p=Q.front;
printf("\n");
while(p!=Q.rear)
{ printf("%d ",p->next->data);p=p->next;}
}
//一下是总代码
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define MAXSIZE 100
typedef int Status;
typedef int QElemType;
typedef struct QNode {/* 结点类型*/
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct { /* 链队列类型*/
QueuePtr front; /* 队头指针*/
QueuePtr rear; /* 队尾指针*/
} LinkQueue;
Status InitQueue (LinkQueue *Q) {
/* 构造一个空队列Q*/
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if (!p) exit (OVERFLOW);
/*存储分配失败*/
p->next = NULL;
Q->front=p;
Q->rear=p;
return OK;
}
Status CreateQueue (LinkQueue *Q,int n) {
/* 创建n个元素的队列Q*/
QueuePtr newnode;
int i;
for (i=1;i<=n;i++)
{newnode=(QueuePtr)malloc(sizeof(QNode));
if (!newnode) exit (OVERFLOW);
/*存储分配失败*/
scanf("%d",&newnode->data);
newnode->next = NULL;
Q->rear->next = newnode;
Q->rear = newnode;
}
return OK;
}
Status EnQueue (LinkQueue *Q,QElemType e) {
QueuePtr newnode;//创建一个新的结点
newnode=(QueuePtr)malloc(sizeof(QNode));//给结点分配一个空间
newnode->data=e;
newnode->next=NULL;
Q->rear->next=newnode;//尾结点指向新结点
Q->rear=newnode;//尾结点变成最后一个结点
return OK;
}
Status DeQueue (LinkQueue *Q,QElemType *e) {
/* 若队列不空,则删除Q的队头元素,
用 e 返回其值,并返回OK;否则返回ERROR*/
/*请完成函数*/
QueuePtr p;//p用来存放删除的元素
if(Q->rear==Q->front)//即队列为空
return ERROR;
p=Q->front->next;//p指向表头元素的下一个元素 ,即要删除的结点
*e=p->data;//存放值到p数据域
Q->front->next=p->next;//p指向要删除结点的下一个结点
if(Q->rear==p) Q->rear=Q->front;
return OK;
free(p);
}
Status QueueTraverse(LinkQueue Q)
{
QueuePtr p;
p=Q.front;
printf("\n");
while(p!=Q.rear)
{ printf("%d ",p->next->data);p=p->next;}
}
main()
{int n,e;
LinkQueue Q;
InitQueue(&Q);
printf("input n=?");
scanf("%d",&n);
CreateQueue(&Q,n);
QueueTraverse(Q);
EnQueue(&Q,30);
QueueTraverse(Q);
DeQueue(&Q,&e);
QueueTraverse(Q);
printf("\ne=%d",e);
}