队列

概念

队列是模拟一组人排队办事行为的数组结构
队列的直观体验:https://www.cs.usfca.edu/~galles/visualization/QueueArray.html
队列

顺序队列

队列采用顺序存储结构时,可利用一维数组来存放节点数据,在数组中ucArray[]中存放队列。

head与tail的引入

由于队列的操作只能在队头和队尾上进行,且不能移动队列中的节点,因此必须有活动的队头和队尾的索引。
图中ucHead为头索引,指向一个满节点ucTail为尾索引,指向一个空节点
队列

用C语言描述

#define MAXSIZE (128)                   //队列的最大长度
typedef struct _queue_t_
{
    unsigned char ucArray[MAXSIZE];     //所用的内存空间
    unsigned char ucHead;               //队头索引
    unsigned char ucTail;               //队尾索引
}queue_t;

出队时

ucHead ++;

入队时

ucArray[ucTail ++] = x;

不足:

当其入队到最后时,要做一次整体搬移动作,以腾出空间。
数据搬移用时会较长,影响入队速度。
而循环队列则不会出现此问题

循环队列(ring-buffer)

什么是循环队列

ucTail=MAXSIZE-1时,即已达到队列空间最末处时,再次入队时,ucTail=0,重新指向队列空间的开始位置。

一般情况

队列

队空

队列

队满

队列

如何判断队空队满

由上图的情况可以知道,ucHead与ucTail已经无法区分,故需要对现有标识物进行改造。
现在引入队列含有节点的个数icount
当队列为空时,icount=0;
当队列为满时,icount=MAXSIZE;
当入队时,icount++;
当出队时,icount--

故循环队列的数据结构可以描述为:

#define MAXSIZE (128)                   //队列的最大长度
typedef struct _ring_queue_t_
{
    unsigned char ucArray[MAXSIZE];     //所用的内存空间
    unsigned char ucHead;               //队头索引
    unsigned char ucTail;               //队尾索引
    unsigned int  iCount;               //有效数据个数
}ring_queue_t;

其实,ucTail=ucHead+iCount。但是会出现ucTail > MAXSIZE -1的情况。故有ucTail=(ucHead+iCount)%MAXSIZE
为了减小数据结构占用的空间,可将上面的数据结构优化为:

#define MAXSIZE (128)                   //队列的最大长度
typedef struct _ring_queue_t_
{
    unsigned char ucArray[MAXSIZE];     //所用的内存空间
    unsigned char ucHead;               //队头索引
    unsigned int  iCount;               //有效数据个数
}ring_queue_t;

如何入队出队

入队

unsigned char ucTail = (ucHead + iCount) % MAXSIZE;
ucArray[ucTail] = x;
icount ++;

出队

ucHead++;
ucHead %= MAXSIZE
iCount --;

队列基本操作

1. 创建
2. 销毁
3. 入队
4. 出队
5. 清空队列
6. 判断队列为空
7. 判断队列为满
8. 获得队列长度
9. 读取队列某一位置的元素值

循环队列的接口与实现

https://gitee.com/hany_li/hany_gear_lib/tree/master/ring_buffer

上一篇:【求助】C语言 visual 2019


下一篇:06-图1 列出连通集 (25 分)