1、基本概念
队列严格按照先进先出的原则,就像排队一样。例如,在银行排队取号办理业务,越先到的取到的号码越小,最先被服务。队列是一种特殊的线性表,它只允许在表的前端进行删除操作,在表的尾部进行插入操作,又被称为FIFO(first in , first out)线性表
2、基本操作
① 初始化队列:主要是开辟一块内存空间用来实例化相关的变量,如头指针和尾指针
② 入队列操作:就是将新元素添加到队尾
③ 出队列操作:取出头元素并删除,再令后一个成为队列的头
④ 判空和判满:主要是判断队列的状态
3、主要类别
队列主要分为两种,一种是顺序队列,另一种是循环队列
4、相关代码
顺序队列
//顺序队列操作
#include <malloc.h>
#include <stdio.h>
#include <mem.h>
#define QUEUEMAX 15
typedef struct {
char name[20];
int age;
} DATA;
typedef struct {
DATA data[QUEUEMAX]; //队列数组
int head; //队头
int tail; //队尾
} Queue;
Queue *init(Queue *q) {
if (q = (Queue *) malloc(sizeof(Queue))) //申请保存队列的内存
{
q->head = 0;//设置队头
q->tail = 0;//设置队尾
return q;
} else
return NULL; //返回空
}
void QueueFree(Queue *q) //释放队列
{
if (q != NULL)
free(q);
}
int QueueIsEmpty(Queue *q) //队列是否为空
{
return (q->head == q->tail);
}
int QueueIsFull(Queue *q)//队列是否已满
{
return (q->tail == QUEUEMAX);
}
int QueueLen(Queue *q) //获取队列长度
{
return (q->tail - q->head);
}
int QueueIn(Queue *q, DATA data)//顺序队列的入队函数
{
if (q->tail == QUEUEMAX) {
printf("队列满了!\n");
return (0);
} else {
q->data[q->tail++] = data;
return (1);
}
}
DATA *QueueOut(Queue *q)//顺序队列的出队
{
if (q->head == q->tail) {
printf("\n队列空了!\n");
return NULL;
} else {
return &(q->data[q->head++]);
}
}
DATA *QueuePeek(Queue *q) //获取队头元素
{
if (QueueIsEmpty(q)) {
printf("\n队列空了!\n");
return NULL;
} else {
return &(q->data[q->head]);
}
}
int main() {
Queue *queue;
queue = init(queue);
DATA data;
printf("%d", queue->tail);
do {
printf("请输入元素(姓名,年龄):");
fflush(stdin); //清空输入缓冲区
scanf("%s%d", &data.name, &data.age);
if(strcmp(data.name,"0")==0)
break;
if(QueueIn(queue, data)==0)
break;
} while (1);
printf("第一个元素(姓名、年龄)是:%s,%d", QueuePeek(queue)->name, QueuePeek(queue)->age);
return 0;
}
循环队列
//
// Created by qcq on 2017/2/25.
//
#include <malloc.h>
#include <stdio.h>
#define MAXSIZE 10
typedef struct {
int data[MAXSIZE]; // 队列元素
int head; // 队头
int tail; // 队尾
} Queue;
// 初始化队列
Queue *init() {
Queue *q;
// 申请内存空间
q = (Queue *) malloc(sizeof(Queue));
if (q == NULL) {
// 分配空间失败
return NULL;
} else {
// 设置队头和队尾
q->head = 0;
q->tail = 0;
}
return q;
}
// 释放队列
void freeQueue(Queue *q) {
if (q != NULL)
free(q);
}
// 判断队列是否为空
int isEmpty(Queue *q) {
if (q->tail == q->head)
return 1;
return 0;
// 或者:return (q->tail==q->head) ;
}
// 判断队列是否已满
int isFull(Queue *q) {
// 循环队列,当队列尾部和头部相邻是为满
if ((q->tail + 1) % MAXSIZE == q->head)
return 1;
return 0;
}
// 入队列
int push(Queue *q, int data) {
// 判断队列是否已满
if (isFull(q) == 1) {
printf("当前队列已满,入队列失败。\n");
return 0;
} else {
// 求出队列尾部的序号
q->tail = (q->tail + 1) % MAXSIZE;
q->data[q->tail] = data;
return 1;
}
}
// 出队列
int pop(Queue *q) {
// 队列为空
if (isEmpty(q) == 1) {
printf("当前队列为空。\n");
return NULL;
} else {
q->head = (q->head + 1) % MAXSIZE;
return q->data[q->head];
}
}
// 获取第一个位置的数据
int top(Queue *q) {
if (isEmpty(q) == 1) {
printf("队列已经空了");
return NULL;
}
return q->data[(q->head + 1) % MAXSIZE];
}
// 求队列的长度
int length(Queue *q) {
int n = q->tail - q->head;
if (n < 0)
return MAXSIZE + n;
return n;
}
// 显示队列全部元素
void show(Queue *q)
{
if (length(q)==0)
printf("当前队列为空,没有元素");
int i ;
for (i = 1; i <= length(q); ++i) {
int j = q->head + i ;
if(j>=MAXSIZE)
j = j%MAXSIZE ;
printf("%d\t",q->data[j]);
}
}
int main() {
// 初始化一个循环队列
Queue *q = init();
int i;
for (i = 0; i < 9; ++i) {
push(q, i);
}
printf("当前队列元素为:");
show(q);
for (i = 1; i < 10; ++i) {
pop(q);
}
printf("\n队列的长度为:%d\n", length(q));
printf("此时的头和尾分别是:%d\t%d\n",q->head,q->tail);
for (i = 1; i < 5; ++i) {
push(q, i);
}
printf("当前队列元素为:");
show(q);
printf("\n此时的头和尾分别是:%d\t%d",q->head,q->tail);
return 0;
}