当前位置:   article > 正文

【数据结构】 循环队列的基本操作 (C语言版)_实验六 循环队列的基本操作

实验六 循环队列的基本操作

目录

一、顺序队列

1、顺序队列的定义:

2、顺序队列的优缺点:

二、循环队列

1、循环队列的定义:

2、循环队列的优缺点:

三、循环队列的基本操作算法(C语言)   

1、宏定义

  2、创建结构体

3、循环队列的初始化 

4、循环队列的销毁

5、循环队列的清空

6、求循环队列的长度

7、循环队列的判空

8、求队头元素

9、循环队列入队

10、循环队列出队

11、遍历队列元素

四、循环队列的基本操作完整代码(C语言)

  五、运行结果


一、顺序队列

1、顺序队列的定义:

顺序队列是由一维数组实现的队列,其中队头元素的下标为0,队尾元素的下标为n-1(n为数组大小),队列的大小在创建时确定,且在队列的生命周期内保持不变。

2、顺序队列的优缺点:

顺序队列的优点:

  1. 空间利用率高:由于数组的大小在创建时确定,因此可以预先分配足够的空间,避免了频繁的内存申请和释放操作,提高了空间利用率。
  2. 存取速度快:由于队列元素在内存中连续存储,因此可以根据下标直接访问队头元素和队尾元素,存取速度快。

顺序队列的缺点:

  1. 不适合处理动态扩展的数据:顺序队列的空间大小在创建时确定,因此无法动态扩展,对于需要处理大规模数据的情况不太适用。
  2. 容易发生假溢出:由于顺序队列的队头和队尾元素不断向后移动,当队列满时,如果继续入队操作,会导致假溢出,即无法再进行入队操作。
  3. 无法充分利用内存的连续性优势:由于顺序队列是基于数组实现的,因此无法充分利用内存的连续性优势,因为队头和队尾元素可能分散在不同的内存位置。

二、循环队列

1、循环队列的定义:

循环队列是一种线性数据结构,它将队列的元素存储在一个连续的数组中,并通过使用循环指针来管理队列的插入和删除操作。循环队列的特点在于,当队列为空时,头尾指针指向同一位置;当队列满时,头尾指针也指向同一位置。 

2、循环队列的优缺点:

循环队列的优点:

  1. 空间利用率高:循环队列使用固定大小的数组来存储元素,无需动态分配内存,因此可以充分利用存储空间。
  2. 时间复杂度稳定:在循环队列中,插入和删除操作具有固定的时间复杂度,这使得循环队列在需要频繁进行插入和删除操作的场景中表现优异。
  3. 无需额外的空间:由于循环队列使用数组实现,因此无需额外的空间来存储元素,从而降低了空间复杂度。

循环队列的缺点:

  1. 队列大小固定:循环队列的大小是固定的,因此在处理大量数据时,可能需要预先分配大量存储空间。如果实际数据量超过预分配的空间,可能会导致数据丢失或程序崩溃。
  2. 判断队列是否为空或满的判断逻辑较复杂:在循环队列中,判断队列是否为空或满的判断逻辑相对复杂。需要同时考虑头尾指针的位置和当前队列的状态。如果处理不当,可能会导致误判或错过一些特殊情况。
  3. 插入和删除操作需要移动元素:虽然循环队列在插入和删除操作时具有固定的时间复杂度,但在实际操作中,仍然需要移动元素以保持队列的连续性和循环性。如果数据量大或者数据不均匀分布,可能会影响操作效率。

三、循环队列的基本操作算法(C语言)   

1、宏定义
  1. #define OK 1
  2. #define ERROR 0
  3. #define OVERFLOW -1
  4. #define MAXSIZE 100
  5. typedef int QElemType;
  6. typedef int Status;
  2、创建结构体
  1. //创建结构体
  2. typedef struct {
  3. QElemType *base;
  4. int front;
  5. int rear;
  6. } SqQueue;
3、循环队列的初始化 
  1. //初始化
  2. Status InitQueue(SqQueue &Q) {
  3. //构造一个空队列
  4. Q.base = new QElemType[MAXSIZE];
  5. if (!Q.base) {
  6. exit(OVERFLOW);
  7. }
  8. Q.front = Q.rear = 0;
  9. return OK;
  10. }
4、循环队列的销毁
  1. //销毁队列
  2. Status DestroyQueue(SqQueue &Q) {
  3. if (Q.base) {
  4. delete Q.base;
  5. }
  6. Q.base = NULL;
  7. Q.front = Q.rear = 0;
  8. return OK;
  9. }
5、循环队列的清空
  1. //清空队列
  2. Status ClearQueue(SqQueue &Q) {
  3. Q.front = Q.rear = 0;
  4. return OK;
  5. }
6、求循环队列的长度
  1. //求长度
  2. Status QueueLength(SqQueue Q) {
  3. return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
  4. }
7、循环队列的判空
  1. Status QueueEmpty(SqQueue Q) {
  2. if (Q.front == Q.rear) {
  3. return true;
  4. } else {
  5. return false;
  6. }
  7. }
8、求队头元素
  1. //求队头元素
  2. Status GetHead(SqQueue Q, QElemType &e) {
  3. if (Q.front == Q.rear) {
  4. return ERROR;
  5. }
  6. e = Q.base[Q.front];
  7. return OK;
  8. }
9、循环队列入队
  1. //循环队列入队
  2. Status EnQueue(SqQueue &Q, QElemType e) {
  3. if ((Q.rear + 1) % MAXSIZE == Q.front) return ERROR;
  4. Q.base[Q.rear] = e;
  5. Q.rear = (Q.rear + 1) % MAXSIZE;
  6. return OK;
  7. }
10、循环队列出队
  1. //循环队列出队
  2. Status DeQueue(SqQueue &Q, QElemType &e) {
  3. if (Q.front == Q.rear) {
  4. return ERROR;
  5. }
  6. e = Q.base[Q.front];
  7. Q.front = (Q.front + 1) % MAXSIZE;
  8. return OK;
  9. }
11、遍历队列元素
  1. //遍历队列
  2. void DisplayQueue(SqQueue Q) {
  3. int i = Q.front;
  4. printf("队列元素为: ");
  5. while (Q.front != Q.rear && (i + MAXSIZE) % MAXSIZE != Q.rear) {
  6. printf("%d ", Q.base[i]);
  7. i++;
  8. }
  9. }
四、循环队列的基本操作完整代码(C语言)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define OK 1
  4. #define ERROR 0
  5. #define OVERFLOW -1
  6. #define MAXSIZE 100
  7. typedef int QElemType;
  8. typedef int Status;
  9. //创建结构体
  10. typedef struct {
  11. QElemType *base;
  12. int front;
  13. int rear;
  14. } SqQueue;
  15. //初始化
  16. Status InitQueue(SqQueue &Q) {
  17. //构造一个空队列
  18. Q.base = new QElemType[MAXSIZE];
  19. if (!Q.base) {
  20. exit(OVERFLOW);
  21. }
  22. Q.front = Q.rear = 0;
  23. return OK;
  24. }
  25. //销毁队列
  26. Status DestroyQueue(SqQueue &Q) {
  27. if (Q.base) {
  28. delete Q.base;
  29. }
  30. Q.base = NULL;
  31. Q.front = Q.rear = 0;
  32. return OK;
  33. }
  34. //清空队列
  35. Status ClearQueue(SqQueue &Q) {
  36. Q.front = Q.rear = 0;
  37. return OK;
  38. }
  39. //求长度
  40. Status QueueLength(SqQueue Q) {
  41. return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
  42. }
  43. //判空
  44. Status QueueEmpty(SqQueue Q) {
  45. if (Q.front == Q.rear) {
  46. return true;
  47. } else {
  48. return false;
  49. }
  50. }
  51. //求队头元素
  52. Status GetHead(SqQueue Q, QElemType &e) {
  53. if (Q.front == Q.rear) {
  54. return ERROR;
  55. }
  56. e = Q.base[Q.front];
  57. return OK;
  58. }
  59. //循环队列入队
  60. Status EnQueue(SqQueue &Q, QElemType e) {
  61. if ((Q.rear + 1) % MAXSIZE == Q.front) return ERROR;
  62. Q.base[Q.rear] = e;
  63. Q.rear = (Q.rear + 1) % MAXSIZE;
  64. return OK;
  65. }
  66. //循环队列出队
  67. Status DeQueue(SqQueue &Q, QElemType &e) {
  68. if (Q.front == Q.rear) {
  69. return ERROR;
  70. }
  71. e = Q.base[Q.front];
  72. Q.front = (Q.front + 1) % MAXSIZE;
  73. return OK;
  74. }
  75. //遍历队列
  76. void DisplayQueue(SqQueue Q) {
  77. int i = Q.front;
  78. printf("队列元素为: ");
  79. while (Q.front != Q.rear && (i + MAXSIZE) % MAXSIZE != Q.rear) {
  80. printf("%d ", Q.base[i]);
  81. i++;
  82. }
  83. }
  84. //功能菜单列表
  85. void show_help() {
  86. printf("******* 功能菜单列表 *******\n");
  87. printf("1----入队------------------\n");
  88. printf("2----求循环队列长度----------\n");
  89. printf("3----出队------------------\n");
  90. printf("4----取队头元素-------------\n");
  91. printf("5----清空循环队列-----------\n");
  92. printf("6----销毁循环队列-----------\n");
  93. printf("7----判断循环队列是否为空-----\n");
  94. printf("8----批量插入元素------------\n");
  95. printf("9----显示队列元素------------\n");
  96. printf("10----退出------------------\n\n");
  97. }
  98. int main() {
  99. SqQueue sq;
  100. //初始化
  101. Status rInitStack = InitQueue(sq);
  102. if (rInitStack == OK) {
  103. printf("循环队列初始化成功!\n");
  104. } else {
  105. printf("循环队列初始化失败!\n");
  106. }
  107. while (1) {
  108. //功能菜单列表
  109. show_help();
  110. int flag;
  111. printf("请输入所需的功能编号:\n");
  112. scanf("%d", &flag);
  113. switch (flag) {
  114. case 1: {//入队
  115. Status EnQueueindex;
  116. printf("请输入插入元素(请在英文状态下输入例如:1): \n");
  117. scanf("%d", &EnQueueindex);
  118. Status rEnQueue = EnQueue(sq, EnQueueindex);
  119. if (rEnQueue == OK) {
  120. printf("向循环队列入队%d成功!\n", EnQueueindex);
  121. } else {
  122. printf("向循环队列入队失败!\n");
  123. }
  124. }
  125. break;
  126. case 2: {//求循环队列的长度
  127. int length = QueueLength(sq);
  128. printf("循环队列的长度为:%d。 \n\n", length);
  129. }
  130. break;
  131. case 3: {//出队
  132. Status DeQueueindex;
  133. Status rDeQueue = DeQueue(sq, DeQueueindex);
  134. if (rDeQueue == OK) {
  135. printf("向循环队列出队%d成功!\n", DeQueueindex);
  136. } else {
  137. printf("向循环队列出队失败!\n");
  138. }
  139. }
  140. break;
  141. case 4: {//求队头元素
  142. Status topData;
  143. Status rGetHead = GetHead(sq, topData);
  144. if (rGetHead == OK) {
  145. printf("向循环队列获取队头元素:%d\n", topData);
  146. } else {
  147. printf("向循环队列获取队头元素失败!\n");
  148. }
  149. }
  150. break;
  151. case 5: { //清空
  152. Status rClearStack = ClearQueue(sq);
  153. if (rClearStack == OK) {
  154. printf("循环队列清空成功!\n");
  155. } else {
  156. printf("循环队列清空失败!\n");
  157. }
  158. }
  159. break;
  160. case 6: {//销毁
  161. Status rDestroyStack = DestroyQueue(sq);
  162. if (rDestroyStack == OK) {
  163. printf("循环队列销毁成功!\n");
  164. } else {
  165. printf("循环队列销毁失败!\n");
  166. }
  167. }
  168. break;
  169. case 7: {///判空
  170. Status ClearStatus = QueueEmpty(sq);
  171. if (ClearStatus == true) {
  172. printf("循环队列为空!\n\n");
  173. } else {
  174. printf("循环队列不为空!\n\n");
  175. }
  176. }
  177. break;
  178. case 8: {//批量插入
  179. int on;
  180. printf("请输入想要插入的元素个数:\n");
  181. scanf("%d", &on);
  182. QElemType array[on];
  183. for (int i = 1; i <= on; i++) {
  184. printf("向循环队列第%d个位置插入元素为:", i);
  185. scanf("%d", &array[i]);
  186. }
  187. for (int i = 1; i <= on; i++) {
  188. Status InsertStatus = EnQueue(sq, array[i]);
  189. if (InsertStatus == OK) {
  190. printf("向循环队列第%d个位置插入元素%d成功!\n", i, array[i]);
  191. } else {
  192. printf("向循环队列第%d个位置插入元素%d失败!\n", i, array[i]);
  193. }
  194. }
  195. }
  196. break;
  197. case 9: {//输出链表元素
  198. DisplayQueue(sq);
  199. printf("\n");
  200. }
  201. break;
  202. case 10: {//退出程序
  203. return 0;
  204. }
  205. break;
  206. default: {
  207. printf("输入错误,无此功能,请检查输入:\n\n");
  208. }
  209. }
  210. }
  211. return 1;
  212. }

  五、运行结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/632413
推荐阅读
相关标签
  

闽ICP备14008679号