什么是队列
队列(Queue)也是一种运算受限的线性表,它限定在表的一端进行插入操作,在表的另一端进行删除操作。队列的结构特性是:先进先出FIFO ( First In First Out)。队列又被称为先进先出表。
队尾:允许插入的一端称作队尾(Rear)
队首:允许删除的一端称作队首(Front)
队列为空的时候 队头front和队尾tail都是0的位置,入队的时候队尾tail往后移动,出队的时候front往队列tail靠拢
因为front的移动,导致数组队列存在伪溢出现象。可以通过循环队列的方式解决伪溢出问题。
链式队列可以通过无表头链表记录头尾的方式实现,插入队列用表尾法插入,遍历表头法删除写法
队列基本操作
-
创建栈:create_queue
-
入队: push_queue
-
出队: pop_queue
-
获取队头元素:front_queue
-
队列是否为空:empty_queue
-
队列元素个数: size_queue
队列应用
具体来说,队列有以下几个用途:
-
任务调度:队列可以用于任务调度,将任务按照它们被提交的顺序排队等待执行。
-
消息传递:队列可以用于消息传递,例如在分布式系统中,可以使用队列来传递消息。
-
广度优先搜索:队列可以用于实现广度优先搜索算法,其中队列用于存储待访问的节点。
-
缓存:队列可以用于实现缓存,例如在计算机网络中,可以使用队列来缓存数据包等。
普通队列(实现队列的基本功能)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//循环队列
typedef int DataType;
typedef struct
{
DataType* data;
int front;
int tail;
int count;
int maxSize;
}Queue;
Queue* create_queue(int maxSize)
{
Queue* q = (Queue*)calloc(1, sizeof(Queue));
assert(q);
q->data = (DataType*)calloc(maxSize, sizeof(DataType));
q->maxSize = maxSize;
q->front = 0;
q->tail = 0;
q->count = 0;
return q;
}
bool empty_queue(Queue* q)
{
return q->count == 0;
}
int size_queue(Queue* q)
{
return q->count;
}
void push_queue(Queue* q, DataType data)
{
if (q->count == q->maxSize)
{
printf("满了!\n");
return;
}
q->data[q->tail] = data;
//q->tail++;
q->tail = (q->tail + 1) % q->maxSize;
q->count++;
}
int front_queue(Queue* q)
{
return q->data[q->front];
}
void pop_queue(Queue* q)
{
if (q->count == 0)
{
printf("空的!\n");
return;
}
//q->front++;
q->front = (q->front + 1) % q->maxSize;
q->count--;
}
int main()
{
Queue* q = create_queue(5);
for (int i = 0; i < 4; i++)
{
push_queue(q, i);
}
pop_queue(q);
pop_queue(q);
push_queue(q, 100);
push_queue(q, 200);
push_queue(q, 300);
while (!empty_queue(q))
{
printf("%d ", front_queue(q));
pop_queue(q);
}
printf("\n");
return 0;
}
链式队列(设置前后节点)
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
//链式队列:表尾插入+表头删除,记录头和尾的方式
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* next;
}Node;
Node* create_node(DataType data)
{
Node* newNode = (Node*)calloc(1, sizeof(Node));
assert(newNode);
newNode->data = data;
newNode->next = NULL;
return newNode;
}
typedef struct
{
int count;
Node* frontNode;
Node* tailNode;
}Queue;
Queue* create_queue()
{
Queue* q = (Queue*)calloc(1, sizeof(Queue));
assert(q);
q->count = 0;
q->frontNode = NULL;
q->tailNode = NULL;
return q;
}
bool empty_queue(Queue* q)
{
return q->count == 0;
}
int size_queue(Queue* q)
{
return q->count;
}
int front_queue(Queue* queue)
{
return queue->frontNode->data;
}
void push_queue(Queue* q, DataType data)
{
Node* newNode = create_node(data);
if (q->count == 0)
{
q->frontNode = newNode;
}
else
{
q->tailNode->next = newNode;
}
q->tailNode = newNode;
q->count++;
}
void pop_queue(Queue* q)
{
if (q == NULL || q->count == 0)
{
printf("队空!\n");
return;
}
Node* nextNode = q->frontNode->next;
free(q->frontNode);
q->frontNode = nextNode;
nextNode == NULL ? (q->tailNode = NULL) : 0;//只有一个节点的话 就需要表尾也置为空
q->count--;
}
int main()
{
Queue* q = create_queue();
for (int i = 0; i < 10; i++)
{
push_queue(q, i);
}
while (!empty_queue(q))
{
printf("%d ", front_queue(q));
pop_queue(q);
}
printf("\n");
return 0;
}
双向队列(数据可以从队列的前和后面传入或者删除)
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* prev;
struct Node* next;
}Node;
Node* create_node(DataType data)
{
Node* newNode = (Node*)calloc(1, sizeof(Node));
assert(newNode);
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
typedef struct
{
int count;
Node* frontNode;
Node* tailNode;
}Deque;
Deque* create_queue()
{
Deque* q = (Deque*)calloc(1, sizeof(Deque));
assert(q);
q->count = 0;
q->frontNode = NULL;
q->tailNode = NULL;
return q;
}
bool empty_queue(Deque* q)
{
return q->count == 0;
}
int size_queue(Deque* q)
{
return q->count;
}
void push_front(Deque* q,DataType data)
{
Node* newNode = create_node(data);
if (q->count == 0)
{
q->tailNode = newNode;
//q->frontNode = newNode;
}
else
{
newNode->next = q->frontNode;
q->frontNode->prev = newNode;
//q->frontNode = newNode;
}
q->frontNode = newNode;
q->count++;
}
void push_back(Deque* q, DataType data)
{
Node* newNode = create_node(data);
if (q->count == 0)
{
q->frontNode = newNode;
//q->tailNode = newNode;
}
else
{
q->tailNode->next = newNode;
newNode->prev = q->tailNode;
//q->tailNode = newNode;
}
q->tailNode = newNode;
q->count++;
}
void pop_front(Deque* q)
{
if (q == NULL || q->count == 0)
{
printf("队空!\n");
return;
}
Node* nextNode = q->frontNode->next;
free(q->frontNode);
q->frontNode = nextNode;
nextNode == NULL ? (q->tailNode = NULL):(nextNode->prev=NULL);
q->count--;
}
void pop_back(Deque* q)
{
if (q == NULL || q->count == 0)
{
printf("队空!\n");
return;
}
Node* prevNode = q->tailNode->prev;
free(q->tailNode);
q->tailNode = prevNode;
prevNode == NULL ? (q->frontNode = NULL) : (prevNode->next = NULL);
q->count--;
}
DataType front_queue(Deque* q)
{
return q->frontNode->data;
}
DataType back_queue(Deque* q)
{
return q->tailNode->data;
}
int main()
{
Deque* q = create_queue();
push_front(q, 1); //3 2 1 66 88 99
push_front(q, 2);
push_front(q, 3);
push_back(q, 66);
push_back(q, 88);
push_back(q, 99);
while (!empty_queue(q))
{
printf("%d ", front_queue(q));
pop_front(q);
}
printf("\n");
return 0;
}
优先队列(设置优先等级)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#define MAX 100
typedef struct Data
{
int priority;
char name[20];
}Data;
typedef struct
{
int count;
Data data[MAX];
}Priqueue;
Priqueue* create_queue()
{
Priqueue* q = (Priqueue*)calloc(1, sizeof(Priqueue));
assert(q);
return q;
}
int size_queue(Priqueue* q)
{
return q->count;
}
bool empty_queue(Priqueue* q)
{
return q->count == 0;
}
void push_queue(Priqueue* q, Data data)
{
if (q->count == MAX)
{
printf("队满");
}
else
{
q->data[q->count++] = data;
}
}
void pop_queue(Priqueue* q, Data* data)
{
if (q == NULL || q->count == 0)
return;
Data minData = q->data[0];
int minIndex = 0;
for (int i = 1; i < q->count; i++)
{
if (minData.priority > q->data[i].priority)
{
minData = q->data[i];
minIndex = i;
}
}
*data = minData;
for (int i = minIndex; i < q->count; i++)
{
q->data[i] = q->data[i + 1];
}
q->count--;
}
int main()
{
Priqueue* q = create_queue();
Data arr[5] = { {1,"张三"},{4,"里斯"},{9,"小美"},{3,"小帅"},{5,"老王"} };
for (int i = 0; i < 5; i++)
{
push_queue(q, arr[i]);
}
while (!empty_queue(q))
{
Data temp;
pop_queue(q, &temp);
printf("%d:%s\n", temp.priority, temp.name);
}
return 0;
}
链式优先队列
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
typedef struct Data
{
int priority;
char name[20];
}Data;
typedef struct Node
{
Data data;
struct Node* next;
}Node;
Node* create_node(Data data)
{
Node* newNode = (Node*)calloc(1, sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
typedef struct
{
int count;
Node* headNode;
}PriQueue;
PriQueue* create_queue()
{
PriQueue* q = (PriQueue*)calloc(1, sizeof(PriQueue));
assert(q);
q->count = 0;
q->headNode = NULL;
return q;
}
bool empty_queue(PriQueue* q)
{
return q->count == 0;
}
int size_queue(PriQueue* q)
{
return q->count;
}
void push_queue(PriQueue* q,Data data)
{
Node* newNode = create_node(data);
if (q->count == 0)
{
q->headNode = newNode;
}
else
{
Node* preNode = NULL;
Node* curNode = q->headNode;
//1 3 8
//4
while (curNode != NULL && curNode->data.priority < data.priority)
{
preNode = curNode;
curNode = preNode->next;
}
if (preNode == NULL)
{
newNode->next = q->headNode;
q->headNode = newNode;
}
else
{
preNode->next = newNode;
newNode->next = curNode;
}
}
q->count++;
}
void pop_queue(PriQueue* q, Data* data)
{
if (q == NULL || q->count == 0)
{
return;
}
Node* nextNode = q->headNode->next;
*data = q->headNode->data;
free(q->headNode);
q->headNode = nextNode;
q->count--;
}
int main()
{
PriQueue* q = create_queue();
Data arr[5] = { {1,"张三"},{4,"里斯"},{9,"小美"},{3,"小帅"},{5,"老王"} };
for (int i = 0; i < 5; i++)
{
push_queue(q, arr[i]);
}
while (!empty_queue(q))
{
Data temp;
pop_queue(q, &temp);
printf("%d:%s\n", temp.priority, temp.name);
}
return 0;
}