队列的显著特点是只能从一端进入,一端出去,他也是一种特殊的顺序表或者链表
(Queue)
由于上述特点,所以队列需要在定义结构体时,加上队头和队尾的索引,(有许多不同的写法,我这里讲的是还加了一个当前队列元素的写法,再判断队中是否为满的时候,可以节省一个队列空间,但同时,多定义了一个变量,也消耗了空间)
所以我的结构体是这样定义的
#define MAX_SIZE 10 //方便根据需求修改
typedef struct Queue
{
int* arr; // 动态数组
int front; // 队头索引
int rear; // 队尾索引
int size; // 当前队列元素
}Queue;
接下来就在实际代码中进行讲解
初始化
//对队列进行初始化
void initQueue(Queue*q)
{
q->arr = (int*)malloc(sizeof(int)*MAX_SIZE);
if (q->arr == NULL)
{
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
q->front = 0;
q->rear = 0;
q->size = 0;
}
入队
int enQueue(Queue *q,int value)
{
//判断队列是否为满
if (q->size == MAX_SIZE )
{
printf("Queue is full(enQueue)\n");
return -1;
}
q->arr[q->rear] = value;
q->rear = (q->rear + 1) % MAX_SIZE;
q->size++;
printf("入队成功\n");
return 0;
}
出队
int outQueue(Queue* q)
{
//出队时首先要对队列是否为空进行判断
if (q->size == 0)
{
printf("Queue is empty!(outQueue)\n");
exit(EXIT_FAILURE);
}
int data = q->arr[q->front];
q->front = (q->front + 1) % MAX_SIZE;
q->size--;
return data;
}
获取队列的队头元素
int getfront(Queue* q)
{
if (q->size == 0)
{
printf("Queue is empty!(get)\n");
exit(EXIT_FAILURE);
}
int data = q->arr[q->front];
return data;
}
代码汇总并测试
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10
typedef struct Queue
{
int* arr; // 动态数组
int front; // 队头索引
int rear; // 队尾索引
int size; // 当前队列元素
}Queue;
//对队列进行初始化
void initQueue(Queue*q)
{
q->arr = (int*)malloc(sizeof(int)*MAX_SIZE);
if (q->arr == NULL)
{
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
q->front = 0;
q->rear = 0;
q->size = 0;
}
//入队
int enQueue(Queue *q,int value)
{
//判断队列是否为满
if (q->size == MAX_SIZE )
{
printf("Queue is full(enQueue)\n");
return -1;
}
q->arr[q->rear] = value;
q->rear = (q->rear + 1) % MAX_SIZE;
q->size++;
printf("入队成功\n");
return 0;
}
//出队
int outQueue(Queue* q)
{
if (q->size == 0)
{
printf("Queue is empty!(outQueue)\n");
exit(EXIT_FAILURE);
}
int data = q->arr[q->front];
q->front = (q->front + 1) % MAX_SIZE;
q->size--;
return data;
}
//获取队列的头元素
int getfront(Queue* q)
{
if (q->size == 0)
{
printf("Queue is empty!(get)\n");
exit(EXIT_FAILURE);
}
int data = q->arr[q->front];
return data;
}
int main()
{
Queue q;
initQueue(&q);
enQueue(&q, 10);
printf("%d", getfront(&q));
printf("\n");
outQueue(&q);
enQueue(&q, 100);
printf("%d", getfront(&q));
return 0;
}
链表实现队列
链表实现队列和顺序表实现队列之前区别有:
链表不需要考虑空间的不够,
在建立结构体时,链表需要用两个指针,一个指向队列的队头.一个指向队列的队尾
初始化和前期准备工作
typedef struct Node
{
struct Node* next;//指向下一个
int data;
}QueueNode;
typedef struct
{
QueueNode* front;//队头指针
QueueNode* rear;//队尾指针
}LinkQueue;
void init(LinkQueue* s)
{
s->front = s->rear = NULL;//初始化时将队头和队尾都赋值为NULL
}
进入队列
void enQueue(LinkQueue*s,int value)
{
QueueNode* p;
p = (QueueNode*)malloc(sizeof(QueueNode));
//这里是使用了malloc的常规写法,判断申请空间是否成功
if (p == NULL)
{
printf("Momery allocation is failed!\n");
exit(EXIT_FAILURE);
}
//对新创的节点初始化
p->data = value;
p->next = NULL;
//分为多种情况,当队列中为空时和不为空
//队列中为空
if (s->rear == NULL)
{
s->front = s->rear = p;
return;
}
//队列中不为空
s->rear->next = p;
s->rear = p;
}
出队列
int outQueue(LinkQueue *s)
{
//判断队列中是否为空
//不要用s->rear == s->front来进行判断,因为我们前面进入队列时,第一个元素进入队列时,
//将队列的首尾指针都指向了第一个元素
if (s->rear == NULL)
{
printf("Queue is empty!\n");
exit(EXIT_FAILURE);
}
int value;
//只有一个节点和多个节点的结果是不一样的,因为只有一个节点时,首尾指针指向的同一个地方
//仅有一个节点
if (s->rear == s->front)
{
value = s->front->data;
QueueNode* temp = s->front;
free(temp);
s->front = s->rear = NULL;
return value;
}
//多个节点
QueueNode* temp = s->front;
value = s->front->data;
s->front = s->front->next;
free(temp);
return value;
}
获得队列中元素的数量代码
int GetLength(LinkQueue s)
{
QueueNode* p;
p = s.front;
int length = 0;
//循环结束条件为p不指向空指针
while (p!= NULL)
{
length++;
p = p->next;
}
return length;
}
int Empty(LinkQueue s)
{
if (s.front == s.rear)
{
return 1;
}
return 0;
}
代码汇总
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
struct Node* next;
int data;
}QueueNode;
typedef struct
{
QueueNode* front;
QueueNode* rear;
}LinkQueue;
void init(LinkQueue* s)
{
s->front = s->rear = NULL;
}
int GetLength(LinkQueue s)
{
QueueNode* p;
p = s.front;
int length = 0;
while (p!= NULL)
{
length++;
p = p->next;
}
return length;
}
int Empty(LinkQueue s)
{
if (s.front == s.rear)
{
return 1;
}
return 0;
}
void enQueue(LinkQueue*s,int value)
{
QueueNode* p;
p = (QueueNode*)malloc(sizeof(QueueNode));
if (p == NULL)
{
printf("Momery allocation is failed!\n");
exit(EXIT_FAILURE);
}
p->data = value;
p->next = NULL;
//分为多种情况
if (s->rear == NULL)
{
s->front = s->rear = p;
return;
}
s->rear->next = p;
s->rear = p;
}
int outQueue(LinkQueue *s)
{
if (s->rear == NULL)
{
printf("Queue is empty!\n");
exit(EXIT_FAILURE);
}
int value;
//仅有一个节点
if (s->rear == s->front)
{
value = s->front->data;
QueueNode* temp = s->front;
free(temp);
s->front = s->rear = NULL;
return value;
}
//多个节点
QueueNode* temp = s->front;
value = s->front->data;
s->front = s->front->next;
free(temp);
return value;
}
int main()
{
//测试
LinkQueue s;
init(&s);
enQueue(&s, 8);
printf("%d\n", outQueue(&s));
enQueue(&s, 10);
enQueue(&s, 10);
enQueue(&s, 10);
enQueue(&s, 9);
printf("%d\n", outQueue(&s));
return 0;