【数据结构】队列

本文更新于个人博客Burnside Blog

在数据结构中,最重要且最基础的两项就是栈与队列。一提到队列(Queue),相信大家都不陌生,它不像栈这个名字一样抽象,而是是一种很形象的结构,因为它本身就可以理解成一个队列。考虑我们排一路纵队在某个窗口办事,办完事的人一定是从队首离开队列,而想要进来办事的人一定是在队尾入队(假设一队人均素质优良,没有插队现象)。队列也是如此,它是一种先入先出的数据结构。

为了方便起见,我们不使用动态方式生成一个队列,或销毁一个队列,我们只考虑一个静态的队列的功能实现。队列中的元素可以是任何的用户自定义类型,为了方便起见,我们假设元素的类型为int,如需要别的类型,只需要灵活处理即可。接下来我们申请一块长度为MaxSize的连续内存来存储这个队列,这时它又被称为顺序队。

int Queue[MaxSize];

这样我们就获得了一个最多能存储MaxSize个元素的队列,在队列中,我们称队首为front,队尾为rear,接下来我们只需要模拟整个入队出队的过程即可。

int enQueue(int x){

    Queue[++rear]=x;

    return rear;

}

int deQueue(){

    return ++front;

}

不难理解,和栈类似,队列在入队操作发生时也只是将队尾的元素赋成新值,出队时将队首前移,这里要注意,队首和队尾在数组中存储的逻辑正好是反着的,也就是队尾的数组下标要比队首大,当然,如果一个队列为空,则队尾和队首的下标相同。

这样我们也可以写一个函数来判断一个队列是否为空。

int empty(){

    return front==rear;

}

这就是队列最简单的实现方式。但注意一点,为什么我们一开始说这个队列最多只能存储MaxSize个元素呢?因为我们发现,这个数组在不断入队出队的过程中,实际上用到的空间只有队首到队尾的这一点空间,而我们申请下来的MaxSize的空间很多是被浪费掉了的,再者,这个队列最多只允许我们进行MaxSize-1次的入队和MaxSize-1次的合法出队操作,因为在进行完这些操作后,队首和队尾的值就都等于MaxSize了,如果再进行入队出队就要访问到非法内存了。

难道队列就是一种如此低效的数据结构吗?并不是这样的,因为我们发明了一种循环队列,这种队列有一个特性,就是如果我的队尾或队首已经到MaxSize而我们想继续操作的时候,下一次的入队或合法的出队操作会使得队首或队尾回到数组下标为0的位置,将申请到的空间循环利用起来,具体实现如下。

入队

bool enQueue(int x){

    if((rear+1)%MaxSize==front) return false;

    Queue[rear=(rear+1)%MaxSize]=x;

    return true;

}

因为循环队列特殊的性质,也就是它的数组下标是循环出现的,我们很容易想到用取余(Mod)来实现数组下标的变换,在此函数中,返回值代表了入队是否成功。

出队

bool deQueue(){

    if(rear==front) return false;

    front=(front+1)%MaxSize;

    return true;

}

与入队相似。

取队首元素

int QueueFront(){

    return Queue[front];

}

此函数的功能是调用队首的元素,书中好像把它和出队操作写在一起了,我不是很推荐这样做,因为调用队首的元素不一定要让其出队。

判断队列是否为空

bool Empty(){

    return front==rear;

}

和普通队列一样判断就可以了。

经过这样的操作,我们就可以得到一个空间利用更高效的队列。当然,还有一种队列叫双端队列(Deque),是支持队首进队出队、队尾进队出队的特殊队列,写法和循环队列类似,读者可以在闲暇时间独立完成,书中貌似也有相关的代码。

书中还介绍了队列的链式存储,也就是链队,实现方式和顺序队类似,不再赘述。此外,还有队内元素保持单调性的单调队列,常用于对动态规划问题(Dynamic Programming,DP)的优化,常用于竞赛,感兴趣可以自行了解。

此外,可能会有部分读者表示我在实现普通队列的时候,没有考虑队列的非法操作(队满时入队,队空时出队),是因为那种队列的实现形式现在已经不用了(因为有更好的循环队列可以使用),因此没有详细处理细节,若想判断的话只需要在两个函数里分别加入if语句判断即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容

  • 1.队列(Queue):具有一定操作约束的线性表 >: 插入和删除操作:只能再一端插入,而在另一端删除 >: 数据...
    BrightHewei阅读 281评论 0 1
  • 定义 队列(queue)是一种先进先出的线性表。它只允许在表的一端进行插入,在另一端进行删除,这如同我们日常生活中...
    jaler189阅读 624评论 1 0
  • 队列的简介 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rea...
    大橘猪猪侠阅读 306评论 0 0
  • 总目录:地址如下看总纲 https://www.jianshu.com/p/929ca9e209e8[https:...
    鄙人_阿K阅读 1,553评论 0 5
  • 队列 队列的基本概念 队列是有限个同类型元素的线性序列 队列也是一种运算受限的线性表,而且是先进先出的线性表 FI...
    1江春水阅读 1,082评论 -1 2