基本概念:
- 和栈相反,队列是一种先进先出(FIFO)的线性表。只允许在一端插入,在另一端删除。
-
允许插入的叫"队尾"(rear),允许删除的叫"队头"(front)。
- 使用场景:操作系统的作业排队。在允许多道程序运行的计算机系统中,同时有几个作业运行。如果运行结果都需要通道输出,则按照请求输出的先后次序排队。每当通道传输完毕可以接受新的输出任务时,队头的作业先从队列中退出作输出操作。申请输出的作业都从队尾进入。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
基本操作:
/* 定义链表队列 */
struct Node //结构体存放节点
struct LinkQueue //存放队头指针和队尾指针,不存放在Node中是为了节省节点入队时占用的内存空间
/* 初始化队列 */
队头指针和队尾指针共同申请一个内存空间
节点下一节指向NULL
注意:头结点的数据为空
/* 入队操作 */
申请新节点
输入的数据elem存放在新节点数据中
新节点下一节指向NULL
尾节点的下一节点指向新节点
队尾指针指向新节点
/* 出队操作 */
节点指针p指向队头结点
队头结点指向第一节点
释放指针p指向的节点
p指向NULL //避免野指针
/* 打印操作 */
由于头节点为空,所以从第二节点开始打印,直到指向NULL时停止打印
实现代码:
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROE 0
#define OVERFLOW -2
typedef int Status;
typedef int QElemType;
typedef struct Node
{
QElemType data;
struct Node *next;
} QNode;
/* 当链式队列的头尾节点指针定义成为一个单独的结构体,避免在新增节点时占用过多的空间 */
typedef struct
{
QNode *front;
QNode *rear;
} LinkQueue;
Status InitQueue(LinkQueue *Q)
{
Q->front = Q->rear = (QNode *)malloc(sizeof(QNode));
if (!Q->front)
exit(OVERFLOW);
Q->rear->next = NULL; //rear.next始终指向NULL,头结点front不动
return OK;
}
Status InQueue (LinkQueue *Q, int elem)
{
QNode *p;
p = (QNode *)malloc(sizeof(QNode));
p->data = elem;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
Status PrintQueue(LinkQueue Q)
{
QNode *p;
p = Q.front->next;
printf("the queue is:");
while(p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
return OK;
}
Status OutQueue(LinkQueue *Q)
{
QNode *p;
int i;
printf("\nthe number of out queue:");
scanf("%d", &i);
while(i != 0)
{
p = Q->front;
Q->front = Q->front->next;
free(p);
i--;
}
p = NULL;
return OK;
}
Status EmptyQueue(LinkQueue Q)
{
if (Q.front->next == NULL)
printf("\nThe queue is empty!\n");
return OK;
}
int main()
{
LinkQueue queue;
InitQueue(&queue);
int elem;
printf("input:");
while(scanf("%d", &elem) != EOF)
{
InQueue(&queue, elem);
}
PrintQueue(queue);
OutQueue(&queue);
PrintQueue(queue);
EmptyQueue(queue);
return OK;
}