队列
一、定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
允许插入的一端称为队尾,允许删除的一端称为队头。队列是一种先进先出的线性表。
二、代码
1、代码(队列的顺序存储结构—循环队列)
#ifndef __SEQQUEUE_H
#define __SEQQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
typedef int states;
#define MAX_SIZE 100
typedef int ElementType;
//队列的顺序存储结构
typedef struct {
ElementType data[MAX_SIZE];
int front;
int rear;
}SeqQueue;
/** 初始化队列 */
states InitQueue(SeqQueue *Q);
/** 入队 */
states EnQueue(SeqQueue *Q, ElementType e);
/** 出队 */
states DeQueue(SeqQueue *Q, ElementType *e);
/** 获取队列中的元素个数 */
int GetQueueLength(SeqQueue *Q);
/** 清空队列 */
states ClearQueue(SeqQueue *Q);
/** 打印队列中的元素 */
void PrintfQueue(SeqQueue *Q);
#endif /* __SEQQUEUE_H */
#include "SeqQueue.h"
/** 初始化队列 */
states InitQueue(SeqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}
/** 入队 */
states EnQueue(SeqQueue *Q, ElementType e)
{
//判断循环队列是否已满
if((Q->rear + 1) % MAX_SIZE == Q->front)
return ERROR;
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAX_SIZE;
return OK;
}
/** 出队 */
states DeQueue(SeqQueue *Q, ElementType *e)
{
//判断队列是否为空
if(Q->front == Q->rear)
return ERROR;
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAX_SIZE;
return OK;
}
/** 获取队列中的元素个数 */
int GetQueueLength(SeqQueue *Q)
{
return ((Q->rear - Q->front + MAX_SIZE) % MAX_SIZE);
}
/** 清空队列 */
states ClearQueue(SeqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}
/** 打印队列中的元素 */
void PrintfQueue(SeqQueue *Q)
{
int i = Q->front;
printf("队列:");
while(i != Q->rear){
printf("%d ",Q->data[i]);
i++;
}
}
2、代码(队列的链式存储结构)
#ifndef __LINKEDQUEUE_H
#define __LINKEDQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
typedef int states;
//队列的链式存储结构
/** 队列中的结点结构 */
typedef struct QueueNode{
ElementType data;
struct QueueNode *next;
}QueueNode;
/** 队列结构 */
typedef struct {
QueueNode *front;
QueueNode *rear;
}LinkedQueue;
/** 队列的初始化 */
states InitLinkedQueue(LinkedQueue *Q);
/** 入队 */
states EnLinkedQueue(LinkedQueue *Q, ElementType e);
/** 出队 */
states DeLinkedQueue(LinkedQueue *Q, ElementType *e);
/** 获取队列中的元素个数 */
int GetLinkedQueueElemNum(LinkedQueue *Q);
/** 清空队列 */
states ClearLinkedQueue(LinkedQueue *Q);
/** 打印队列中的元素 */
void PrintfLinkedQueue(LinkedQueue *Q);
#endif /* __LINKEDQUEUE_H */
#include "LinkedQueue.h"
/** 队列的初始化 */
states InitLinkedQueue(LinkedQueue *Q)
{
Q->front = (QueueNode *)malloc(sizeof(QueueNode));
Q->rear = Q->front;
Q->front->next = NULL;
return OK;
}
/** 入队 */
states EnLinkedQueue(LinkedQueue *Q, ElementType e)
{
QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode));
printf("node = 0x%x\n",node);
node->data = e;
node->next = NULL;
Q->rear->next = node;
Q->rear = node;
return OK;
}
/** 出队 */
states DeLinkedQueue(LinkedQueue *Q, ElementType *e)
{
QueueNode *node;
//判断队列是否为空
if(Q->rear == Q->front)
return ERROR;
node = Q->front->next;
*e = node->data;
Q->front->next = node->next;
if(Q->rear == node){ //重点理解
Q->rear = Q->front; //rear指针是移动的,front->next指针也是移动的
//front指针是不动的,
}
free(node);
return OK;
}
/** 获取队列中的元素个数 */
int GetLinkedQueueElemNum(LinkedQueue *Q)
{
int ElemNbr = 0;
QueueNode *node = Q->front->next;
while(node){
node = node->next;
ElemNbr++;
}
return ElemNbr;
}
/** 清空队列 */
states ClearLinkedQueue(LinkedQueue *Q)
{
QueueNode *p,*q;
p= Q->front->next;
while(p){
q = p->next;
free(p);
p = q;
}
Q->rear = Q->front;
Q->front->next = NULL;
return OK;
}
/** 打印队列中的元素 */
void PrintfLinkedQueue(LinkedQueue *Q)
{
QueueNode *node = Q->front->next;
while(node){
printf("%d ",node->data);
node = node->next;
}
}
三、编程笔记
-
顺序队列
1、顺序队列的结构表示
typedef struct {
int front; //队头指针
int rear; //队尾指针
ElementType datas[MAX_SIZE];
}QueueList;
2、队列为空的判断条件:队头指针与队尾指针相等时,队列为空。
3、队列已满的判断条件:队尾指针加1等于队头指针时,队列已满。
这里是人为规定的,为了和队列为空进行区别。因此,数组中的一个元素是不用的。
4、获取队列中的元素个数:
当rear > front时,num = rear - front;
当rear < front时,num = rear + MAX_SIZE - front;
合并成一个表达式:num = (rear + MAX_SIZE - front)%MAX_SIZE; -
链式队列
1、采用了头结点,
2、队列为空的判断条件
3、将队列中的最后一个元素出队之后,需要将队列设置为空。所以在出队时要进行判断。
4、front指针是不变的,rear指针是移动的,除了队列为空外,总是指向队尾结点的地址。
front->next指针也是移动的,每当有元素入队后,指向该结点的地址。
注:出队时,需要判断出队是否为队尾元素,若是队尾元素的话,要将 rear = front;(顺序不能反)