当前位置:   article > 正文

数据结构——顺序队列【c语言版】_队列的顺序存储结构源代码

队列的顺序存储结构源代码

队列(quque)简称队只允许在表的一端输入,在表的另一端删除(操作受限制的线性表)

把进行插入的一段叫做队尾(表尾),把进入删除的一端叫做队首或队头(表头)。

队列最主要的特点:先进先出,FIFO(first in first out)

队列有其实有三种:顺序队列 循环队列链式队列

        下面是采用采用顺序存储结构来实现的顺序队

        假设栈的元素个数最大不超过正整数MaxSize,所以元素具有同一数据类型(ElemType),用下来方式来声明顺序队列的类型SqQueue:

  1. #define MaxSize 128 //队列的最大容量
  2. typedef int ElemType; //队列中元素类型
  3. typedef struct
  4. {
  5. ElemType data[MaxSize];
  6. int front; //存储队头元素前一个单元的下标
  7. int rear; //队尾指针
  8. }SqQueue;

对于顺序队来说,有以下四个非常重要的要素:

        1.队空条件:SQ->front == SQ->rear ==  -1

        2.队满条件:SQ->rear == MaxSize - 1

        3.进队操作:先将rear+1,再将元素e放在rear指向的位置

        4.出队操作:先将front+1,再将取出front指向的位置上的元素

1)队列初始化

        构造一个空的队列SQ,将front和rear指针都指向-1,代码如下:

  1. void InitQueue(SqQueue *SQ)
  2. {
  3. SQ->front = SQ->rear = -1; //把对头和队尾指针同时置-1
  4. }

2)判断队列是否为空

        顺序队列中,判断队列是否为空,只需要判断SQ->front == SQ->rear的条件成立即可,代码如下:

  1. //判断队列为空
  2. int IsEmpty(SqQueue* SQ)
  3. {
  4. if (SQ->front == SQ->rear)
  5. {
  6. return 1;
  7. }
  8. return 0;
  9. }

3)判断队列是否为满

                顺序队列中,判断队列是否为满,只需要判断SQ->rear == MaxSize - 1的条件成立即可,代码如下:

  1. //判断队列是否为满
  2. int IsFull(SqQueue* SQ)
  3. {
  4. if (SQ->rear == MaxSize-1)
  5. {
  6. return 1;
  7. }
  8. return 0;
  9. }

4)入队

        在队列不满条件下先将rear+1,再将元素e放在rear指向的位置,因此该操作需要先判断队列是否已满,避免上溢,这里可以调用IsFull(SqQueue* SQ)来判断,代码如下:

  1. //入队,先将rear+1,将元素e插入到队列SQ中
  2. void EnterQueue(SqQueue* SQ,ElemType e)
  3. {
  4. if (IsFull(SQ))
  5. {
  6. printf("队列已满\n");
  7. return 0;
  8. }
  9. SQ->rear = SQ->rear + 1; //队尾指针后移一位
  10. SQ->data[SQ->rear] = e; //在队尾插入元素e
  11. }

5)出队

        在队列不空条件下先将front+1,再将取出front指向的位置上的元素,因此该操作需要先判断队列是否为空,避免下溢,这里可以调用IsEmpty(SqQueue* SQ)来判断,代码如下:

  1. //出队,先将队头指针front后移一位,取出front指向的元素e出
  2. int DeleteQueue(SqQueue* SQ,ElemType e)
  3. {
  4. if (IsEmpty(SQ))
  5. {
  6. printf("队列为空!\n");
  7. return 0;
  8. }
  9. SQ->front = (SQ->front)+1; //队尾指针后移一位
  10. e = SQ->data[SQ->front]; //出队元素值
  11. return e;
  12. }

6)打印队列中的元素

        从队首到队尾,代码如下:

  1. //打印队列中的与元素
  2. void PrintQueue(SqQueue* SQ)
  3. {
  4. assert(SQ);
  5. int i = SQ->front;
  6. while(i<SQ->rear)
  7. {
  8. printf("%-3d", SQ->data[i]);
  9. i++;
  10. }
  11. printf("\n");
  12. }

下面是入队、出栈以及打印出队列元素的操作:

  1. int main()
  2. {
  3. SqQueue SQ;
  4. ElemType e;
  5. //初始化队列
  6. InitQueue(&SQ);
  7. //入队
  8. EnterQueue(&SQ, 1);
  9. EnterQueue(&SQ, 2);
  10. EnterQueue(&SQ, 3);
  11. EnterQueue(&SQ, 4);
  12. EnterQueue(&SQ, 5);
  13. EnterQueue(&SQ, 6);
  14. EnterQueue(&SQ, 7);
  15. EnterQueue(&SQ, 8);
  16. EnterQueue(&SQ, 10);
  17. EnterQueue(&SQ, 12);
  18. EnterQueue(&SQ, 15);
  19. EnterQueue(&SQ, 16);
  20. //出队
  21. printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
  22. printf("\n");
  23. printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
  24. printf("\n");
  25. printf("队列中的元素为:");
  26. PrintQueue(&SQ);
  27. printf("\n");
  28. return 0;
  29. }

测试结构如下:

总结:

        实际上,我们非常不建议使用顺序队,因为无论是入队还是出队,它们的指针front,rear都是加1,当队列中有元素出队而SQ->rear == MaxSize时,再进行入队,会显示队满,但其实front的前面还要很多空间,造成空间的浪费,存在假溢现象, 所以一般情况下都采用循环队列的方法来解决。

最后再附上完整代码:

  1. /*
  2. 设立一个存储队头元素前一个单元的下标front ,一个队尾指针rear ,分别指向存储队头元素前一个单元的下标和队尾元素。
  3. 初始化:front=rear=-1。
  4. 队列为空:front=rear。
  5. 队满:rear=MaxSize。
  6. 入队:先将rear加1,再将新元素插入rear所指的位置。
  7. 出队:先将real加1,再删取出front所指的元素。
  8. */
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <Windows.h>
  12. #define MaxSize 128 //队列的最大容量
  13. typedef int ElemType; //队列中元素类型
  14. typedef struct
  15. {
  16. ElemType data[MaxSize];
  17. int front; //存储队头元素前一个单元的下标
  18. int rear; //队尾指针
  19. }SqQueue;
  20. //队列初始化,将队列初始化为空队列
  21. void InitQueue(SqQueue *SQ)
  22. {
  23. SQ->front = SQ->rear = -1; //把对头和队尾指针同时置-1
  24. }
  25. //判断队列为空
  26. int IsEmpty(SqQueue* SQ)
  27. {
  28. if (SQ->front == SQ->rear)
  29. {
  30. return 1;
  31. }
  32. return 0;
  33. }
  34. //判断队列是否为满
  35. int IsFull(SqQueue* SQ)
  36. {
  37. if (SQ->rear == MaxSize-1)
  38. {
  39. return 1;
  40. }
  41. return 0;
  42. }
  43. //入队,先将rear+1,将元素e插入到队列SQ中
  44. void EnterQueue(SqQueue* SQ,ElemType e)
  45. {
  46. if (IsFull(SQ))
  47. {
  48. printf("队列已满\n");
  49. return 0;
  50. }
  51. SQ->rear = SQ->rear + 1; //队尾指针后移一位
  52. SQ->data[SQ->rear] = e; //在队尾插入元素e
  53. }
  54. //出队,先将队头指针front后移一位,取出front指向的元素e出
  55. int DeleteQueue(SqQueue* SQ,ElemType e)
  56. {
  57. if (IsEmpty(SQ))
  58. {
  59. printf("队列为空!\n");
  60. return 0;
  61. }
  62. SQ->front = (SQ->front)+1; //队尾指针后移一位
  63. e = SQ->data[SQ->front]; //出队元素值
  64. return e;
  65. }
  66. //打印队列中的与元素
  67. void PrintQueue(SqQueue* SQ)
  68. {
  69. assert(SQ);
  70. int i = SQ->front;
  71. while(i<SQ->rear)
  72. {
  73. printf("%-3d", SQ->data[i]);
  74. i++;
  75. }
  76. printf("\n");
  77. }
  78. int main()
  79. {
  80. SqQueue SQ;
  81. ElemType e;
  82. //初始化队列
  83. InitQueue(&SQ);
  84. //入队
  85. EnterQueue(&SQ, 1);
  86. EnterQueue(&SQ, 2);
  87. EnterQueue(&SQ, 3);
  88. EnterQueue(&SQ, 4);
  89. EnterQueue(&SQ, 5);
  90. EnterQueue(&SQ, 6);
  91. EnterQueue(&SQ, 7);
  92. EnterQueue(&SQ, 8);
  93. EnterQueue(&SQ, 10);
  94. EnterQueue(&SQ, 12);
  95. EnterQueue(&SQ, 15);
  96. EnterQueue(&SQ, 16);
  97. //出队
  98. printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
  99. printf("\n");
  100. printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
  101. printf("\n");
  102. printf("队列中的元素为:");
  103. PrintQueue(&SQ);
  104. printf("\n");
  105. return 0;
  106. }

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

闽ICP备14008679号