![C#程序员面试算法宝典](https://wfqqreader-1252317822.image.myqcloud.com/cover/733/33643733/b_33643733.jpg)
2.2 如何实现队列
难度系数:★★★☆☆ 被考察系数:★★★★☆
题目描述:
实现一个队列的数据结构,使其具有入队列、出队列、查看队列首尾元素、查看队列大小等功能。
分析与解答:
与实现栈的方法类似,队列的实现也有两种方法,分别为采用数组来实现和采用链表来实现。下面分别详细介绍这两种方法。
方法一:数组实现
下图给出了一种最简单的实现方式,用front来记录队列首元素的位置,用rear来记录队列尾元素往后一个位置。入队列的时候只需要将待入队列的元素放到数组下标为rear的位置,同时rear++,出队列的时候只需要执行front++即可。
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_74_02.jpg?sign=1739275737-y8VMLSFO7lLmNAEQr9CLept6cbk5pzE8-0-c06b3acff9eacea0e9c1a05c09ba14b8)
为了简化实现,下面代码定义的队列最大的空间为10,实现代码如下所示:
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_74_03.jpg?sign=1739275737-SsfSfxGDxi9ahgpuneuFebtM3pw3g5HL-0-703f51e789b3ed600f47e7e75ec3a1f1)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_75_01.jpg?sign=1739275737-AgBRMFnfjxO9a0NpoweJ2xWFPptT1obd-0-8a93c1a63682c28e50267c1927ca1675)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_76_01.jpg?sign=1739275737-ehKaSSUnbqHOE5adSUh3lIrqGMzpK6Ze-0-7b25311e3864848710f7ae8c97be655c)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_77_01.jpg?sign=1739275737-wgTMidHxgmkSjdWlZe7qVnj7qnJx5TuJ-0-441fe63c014cb709c9de63e2b8e4439a)
程序的运行结果为
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_77_02.jpg?sign=1739275737-O0BIUyUe9Z9oSBw6EymG5JziZ3yTvNL0-0-07d844f6d00b542f4c6686e3c6690c9e)
以上这种实现方法最大的缺点为:出队列后数组前半部分的空间不能够充分的利用,解决这个问题的方法为把数组看成一个环状的空间(循环队列)。当数组最后一个位置被占用后,可以从数组首位置开始循环利用,具体实现方法可以参考数据结构的课本。
方法二:链表实现
采用链表实现队列的方法与实现栈的方法类似,分别用两个指针指向队列的首元素与尾元素,如下图所示。用pHead来指向队列的首元素,用pEnd来指向队列的尾元素。
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_77_03.jpg?sign=1739275737-Xhgb2NcbsChHm50gDLCy7pKmnSdCEf7y-0-31ca0bf4765b7d42a83c9e6fce34db78)
在上图中,刚开始队列中只有元素1、2和3,当新元素4要进队列的时候,只需要上图中(1)和(2)两步,就可以把新结点连接到链表的尾部,同时修改pEnd指针指向新增加的结点。出队列的时候只需要(3)一步,改变pHead指针使其指向pHead->next,此外也需要考虑结点所占空间释放的问题。在入队列与出队列的操作中也需要考虑队列尾空的时候的特殊操作,实现代码如下所示:
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_77_04.jpg?sign=1739275737-vX5n5GTWABtfpipawkCifHfg1hdNa565-0-8d9a696dcd16211815864978d27409e7)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_78_01.jpg?sign=1739275737-FgBbPCfpkweZxU1Yr6STwYKA0JbASHHe-0-1375613b4f4a297c85a6943235e33bcd)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_79_01.jpg?sign=1739275737-AvtjSbYUtGzqM2mfPdssCmKc2lEpsgnD-0-ccd31124024c94f68a97da9dd1e1d594)
程序的运行结果为
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_79_02.jpg?sign=1739275737-BaDlybGomuJ31CYacN7WzzFxjYy0CAsd-0-6d09f2f20d42546721d63790eb7c53bf)
显然用链表来实现队列有更好的灵活性,与数组的实现方法相比,它多了用来存储结点关系的指针空间。此外,也可以用循环链表来实现队列,这样只需要一个指向链表最后一个元素的指针即可,因为通过指向链表尾元素可以非常容易地找到链表的首结点。