队列(循环队列)

Posted lanhaicode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了队列(循环队列)相关的知识,希望对你有一定的参考价值。

队列

队列一般分为两类:链式队列和顺序队列

         链式队列---链式队列即用链表实现的队列

         顺序队列---顺序队列是用数组实现的队列,顺序队列通常必须是循环队列

1、基本概念:

  队列是指允许在一端进行插入,在另一端进行删除的线性表,又称“先进先出”的线性表

  队列是一种特殊的线性结构,它只允许在队列的首部(head)进行删除操作,这称为出队

  队尾:允许插入的一端,用尾指针指向队尾元素的后一位置

  排头:允许删除的一端,用头指针指向头元素

 

循环队列(顺序队列)的实现:

 

 1 #include <stdio.h>
 2 
 3 #define LENGTH 11    /*定义数组最大长度 */
 4 #define OUT 1        /* 出队 */
 5 #define GET 2        /* 入队 */
 6 struct queue
 7 {
 8     int data[LENGTH];
 9     int head;    /* 队首 */
10     int tail;    /* 队尾 */
11 };
12 /* 循环队列的实现 */
13 main()
14 {
15     struct queue q;
16     int i;
17     int kk = 0;
18     /* 初始化队列 */
19     q.head = q.tail = 0;    /*队首队尾初始化 */
20     /* 依次插入10个数 */
21     for (i = 0; i < LENGTH - 1; i++)
22     {
23         scanf_s("%d", &q.data[q.tail]);
24         q.tail = (q.tail + 1) % LENGTH;
25     }
26     while (1)
27     {
28         if (q.head == q.tail)
29         {
30             printf("队列已空");
31             break;
32         }
33         printf("出队:1
入队:2
");
34         scanf_s("%d", &kk);
35         if (kk == OUT)
36         {
37             
38             q.head = (q.head + 1) % LENGTH;
39         }
40         else if (kk == GET)
41         {
42             if (q.head == (q.tail + 1) % LENGTH)
43             {
44                 printf("队列已满");
45                 break;
46             }
47             printf("输入入队元素:
");
48             scanf_s("%d", &q.data[q.tail]);
49             q.tail = (q.tail + 1) % LENGTH;
50         }
51 
52         if (q.tail != q.head)
53         {
54             printf("队列中剩余元素:");
55             for (i = q.head; ;)
56             {
57                 printf("%d ", q.data[i]);
58                 i = (i + 1) % LENGTH;
59                 if(i == q.tail)
60                 {
61                     putchar(
);
62                     break;
63                 }
64             }
65         }
66     }
67     printf("队列已满或已为空");
68 
69 
70     return 0;
71 }

 

 

2、为什么顺序队列通常必须是循环队列

循环队列是针对顺序队列中最大内存空间有限的一种解决方法,当队列(数组)不可再插入新元素但队列的实际可用空间并未占满的问题的一种合理的解决方案

3、与普通顺序队列的区别

普通顺序队列在插入新元素(入队)时为q.tail++,删除旧元素(出队)时为q.head++(q.tail和q.head都为int型,但为了描述方便这里说成指针),在出队后

就会出现实际可用空间并未占满但无法插入新元素的问题强行插入会造成数组越界,也不宜继续扩大数组空间,造成了空间上的浪费

循环队列的核心在于队头指针和队尾指针的增加方式

q.head = (q.head + 1) % LENGTH;

q.tail = (q.tail + 1) % LENGTH;

这样实现了臆想上存储空间的弯曲效果,也解决了空间上的浪费

值得注意的是

q.head指向的是队首元素

q.tail指向的是队尾元素的后一位,浪费了一位空间,例如数组q.data[11]插入10个元素后q.tail指向的是q.data[10]即q.tail = 10;

4、循环队列的新问题

当队列为空时q.head = q.tail,当队列为满时也有q.head = q.tail造成了判断队列是空还是满的二义性

解决方法:1.增加一个参数,使删除元素为1,插入元素为0

                       2.增加一个参数,记录队列的元素个数即长度

          3.空出一个单元,令if(q.head == (q.tail + 1) % LENGTH)为队列为满的条件,以此解决二义性

5、注意

循环队列的头指针和尾指针的减少或增加方式

队列为满或空的判定条件

循环队列参考链接:

https://www.cnblogs.com/chenliyang/p/6554141.html                    该篇比较详细

https://blog.csdn.net/smile_zhangw/article/details/80894159

https://www.cnblogs.com/xiaoyouPrince/p/8125852.html

https://www.cnblogs.com/xing901022/p/3534937.html

 

(编译器:Microsoft Visual C++ 2010 Express)

以上是关于队列(循环队列)的主要内容,如果未能解决你的问题,请参考以下文章

用java实现循环队列?

java-----循环队列

java-----循环队列

如何只用队头指针实现顺序循环队列?

栈与队列:循环队列算法+可执行代码

循环队列