v1.0 中的队列是存储在数组中,如果需要一个比较大的队列,用数组的方式有时候并不太合适,更常见的方式是使用malloc来动态分配队列的存储空间。所以本文介绍一种基于堆的简单环形队列(v2.0)。
基于堆的简单环形队列
#define SIZE 5 //宏控制数组的大小
int * queue = NULL; //队列指针,队列的每个元素是一个int
int head = 0; //头索引
int tail = 0; //尾索引
队列判空
int is_empty()
{
return head == tail;// 头索引和尾索引相等,那么该队列为空,即队列里面没有存储int。
}
队列判满
int is_full()
{
return (tail+1)%SIZE == head;// 若尾索引+1的值 取模 SIZE 等于 头索引,则队列已满。
}
入队
int enqueue(int val)
{
if (is_full()) // step1: 队列判满
{
printf("queue is full...\n");
return 0;
}
// 队列未满
queue[tail] = val; // step2: 将val的值存储到queue[tail]中
tail = (tail+1)%SIZE; // step3: 尾索引循环加1
return 1;
}
出队
int dequeue(int *val)
{
if (is_empty()) // step1: 队列判空
{
printf("queue is empty...\n");
return 0;
}
// 队列不为空
*val = queue[head]; // step2: 将头索引指向的元素取出
head = (head+1)%SIZE; // step3: 头索引循环加1
return 1;
}
simple_ring_queue.c
int main()
{
int i = 0;
int val = 0;
queue = (int*)malloc(SIZE*sizeof(int)); //malloc分配 环形队列的存储空间
for (i = 0; i < SIZE; i++)
{
if (enqueue(i))
printf("queue[%d]=%d\n", i, queue[i]);
}
for (i = 0; i < SIZE; i++)
{
if (dequeue(&val))
printf("val=%d\n", val);
}
for (i = 0; i < SIZE; i++)
{
if (enqueue(i))
printf("queue[%d]=%d\n", i, queue[i]);
}
for (i = 0; i < SIZE; i++)
{
if (dequeue(&val))
printf("val=%d\n", val);
}
printf("head=%d, tail=%d\n", head, tail);
free(queue); // 释放队列空间
return 0;
}
以上便是环形队列的2.0版本,基于堆的简单环形队列。如果你能完全理解环形队列v1.0和v2.0,那么恭喜你,已掌握环形队列的核心。但是你会发现,这两个版本的接口扩展性很差,需要更好的接口设计。
完整代码路径
https://gitee.com/yellow_mamba/c_tutorial/tree/master/queue/v2.0
目录结构
|-- bin
|-- build
|-- CMakeLists.txt
|-- readme.md
`-- src
`-- simple_ring_queue.c
编译&运行
cd build
cmake ..
make
../bin/queue
QQ讨论群:679603305