数据结构与算法-队列【C语言】
一、数据结构与算法-队列
队列的规则:先进先出;队列中的元素无法被遍历
1.1 顺序存储的队列
顺序存储队列的存储结构如下所示,
1.1.1 顺序存储队列的入队列
使用顺序存储结构表示队列时,首先申请足够大的内存空间建立一个数组,除此之外,为了满足队列从队尾存入数据元素,从队头删除数据元素,还需要定义两个指针分别作为头指针和尾指针。当有数据元素进入队列时,将数据元素存放到队尾指针指向的位置,然后队尾指针增加 1;
// 入栈
void Push_SeqStack(SeqStack* stack, void* data) {
if (stack == NULL || stack->size > MAX_SIZE || data == NULL) return;
// 队尾插入元素
stack->data[stack->size] = data;
// 队尾指针向后移动一位
stack->size++;
}
1.1.2 顺序存储队列的出队列
出栈如下图所示,
// 出队
void Pop_SeqQueue(SeqQueue* queue) {
if (queue == NULL || queue->size == 0) return;
// 将对头元素后的所有元素整体向前移动一位
for (int i = 0; i < queue->size - 1; i++) {
queue->data[i] = queue->data[i + 1];
}
// 队尾指针向前移动一位
queue->size--;
}
1.1.3 完整代码
// 头文件SeqQueue.h
#ifndef SEQQUEUE_H
#define SEQQUEUE_H
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 1024
// 定义队列结构体
typedef struct SEQQUEUE {
void* data[MAX_SIZE];
int size;
}SeqQueue;
// 初始化
SeqQueue* Init_SeqQueue();
// 入队列
void Push_SeqQueue(SeqQueue* queue, void* data);
//返回对头元素
void* Front_SeqQueue(SeqQueue* queue);
// 出队
void Pop_SeqQueue(SeqQueue* queue);
// 返回队尾元素
void* Back_SeqQueue(SeqQueue* queue);
// 返回当前队列中元素的个数
int Size_SeqQueue(SeqQueue* queue);
// 清空队列
void Clear_SeqQueue(SeqQueue* queue);
// 销毁
void FreeSpace_SeqQueue(SeqQueue* queue);
#endif // !SEQQUEUE_H
// 源文件SeqQueue.c
#include"SeqQueue.h"
// 初始化
SeqQueue* Init_SeqQueue() {
// 开辟SeqQueue空间
SeqQueue* queue = (SeqQueue*)malloc(sizeof(SeqQueue));
// 初始化队列
for (int i = 0; i < MAX_SIZE; i++) {
queue->data[i] = NULL;
}
queue->size = 0;
return queue;
}
// 入队列
void Push_SeqQueue(SeqQueue* queue, void* data) {
if (queue == NULL || data == NULL) return;
queue->data[queue->size] = data;
queue->size++;
}
//返回对头元素
void* Front_SeqQueue(SeqQueue* queue) {
if (queue == NULL || queue->size == 0)return NULL;
return queue->data[0];
}
// 出队
void Pop_SeqQueue(SeqQueue* queue) {
if (queue == NULL || queue->size == 0) return;
for (int i = 0; i < queue->size - 1; i++) {
queue->data[i] = queue->data[i + 1];
}
queue->size--;
}
// 返回队尾元素
void* Back_SeqQueue(SeqQueue* queue) {
if (queue == NULL || queue->size == 0) return NULL;
return queue->data[queue->size-1];
}
// 返回当前队列中元素的个数
int Size_SeqQueue(SeqQueue* queue) {
if (queue == NULL || queue->size == 0) return 0;
return queue->size;
}
// 清空队列
void Clear_SeqQueue(SeqQueue* queue) {
if (queue == NULL || queue->size == 0) return;
queue->size = 0;
}
// 销毁
void FreeSpace_SeqQueue(SeqQueue* queue) {
if (queue == NULL) return;
free(queue);
}
// main.c 测试文件
#include"SeqQueue.h"
typedef struct PERSON {
char name[64];
int age;
}Person;
int main() {
// 初始化栈
SeqQueue* queue = Init_SeqQueue();
// 创建元素
Person p1 = { "aaa", 10 }, p2 = { "bbb", 20 }, p3 = { "ccc", 30 }, p4 = { "ddd", 40 }, p5 = { "eee", 50 };
// 将元素压入队尾中
Push_SeqQueue(queue, &p1);
Push_SeqQueue(queue, &p2);
Push_SeqQueue(queue, &p3);
Push_SeqQueue(queue, &p4);
Push_SeqQueue(queue, &p5);
// 输出队尾元素
printf("输出队尾元素:\n");
Person* pp = (Person*)Back_SeqQueue(queue);
printf("name: %s, age: %d\n", pp->name, pp->age);
printf("\n栈中所有元素:\n");
// 取出对头元素
while (Size_SeqQueue(queue) > 0) {
// 取队头元素
Person* p = (Person*)Front_SeqQueue(queue);
printf("name: %s, age: %d\n", p->name, p->age);
// 出队列
Pop_SeqQueue(queue);
}
return 0;
}
1.1.4 运行结果
运行结果如下所示,
1.2 链式队列
1.2.1 链式栈的存储结构
链式栈的存储结构如下所示,
1.2.2 链式队列中压入元素
// 入队列
void Push_LinkQueue(LinkQueue* queue, QueueNode* data) {
if (queue == NULL || data == NULL) return;
// 在队尾插入元素
// 1) 创建辅助结点
QueueNode* pCurrent = &(queue->head);
for (int i = 0; i < queue->size; i++) {
pCurrent = pCurrent->next;
}
data->next = pCurrent->next;
pCurrent->next = data;
queue->size++;
}
1.2.3 出队列
void Pop_LinkQueue(LinkQueue* queue) {
if (queue == NULL || queue->size == 0) return;
queue->head.next = queue->head.next->next;
}
1.2.4 运行结果
二、参考链接
1、数据结构与算法知识点总结
2、C++教程
3、队列(Queue)