当前位置:   article > 正文

数据结构——循环队列【c语言版】_写出循环队列数据元素类型为字

写出循环队列数据元素类型为字

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

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

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

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

       为了避免顺序队列中出现的假溢出现象,我们只需要把数组的前后端连接起来,形成一个环形数组,在逻辑上把这个环称为环形队列或者循环队列。

        下面是循环队列的实现过程:

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

  1. #define MAXSIZE 10 //队列的最大容量
  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 

        2.队满条件:SQ->rear+1)%MAXSIZE == SQ->front

        3.进队操作:

                            SQ->rear = (SQ->rear + 1) % MAXSIZE;
                            SQ->data[SQ->rear] = e;                           

                            先将 SQ->rear = (SQ->rear + 1) % MAXSIZE,再将元素e放在rear指向的位置

        4.出队操作:

                            SQ->front = (SQ->front+1) % MAXSIZE;
                            *e = SQ->data[SQ->front];

                             先将 SQ->front = (SQ->front+1) % MAXSIZE,再将取出front指向的位置上的元                               素并存放于e中

1)队列初始化

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

  1. void InitQueue(SQQueue* SQ)
  2. {
  3. SQ->front = SQ->rear = -1;
  4. }

2)判断队列是否为空

        注:为了区分空和满,任意时候都预留1个单元出来x的下一个:(x+1)%MAXSIZE

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

  1. //判断队列为空
  2. void InitQueue(SQQueue* SQ)
  3. {
  4. SQ->front = SQ->rear = -1;
  5. }

3)判断队列是否为满

                循环队列中,判断队列是否为满,只需要判断(SQ->rear+1)%MAXSIZE == SQ->front的条件成立即可,

特别注意,循环队列中的特殊情况,初始状态下SQ->front == -1,当执行进队操作SQ->rear == MAXSIZE - 2时队列已满,需要将这一特殊情况考虑,代码如下:

  1. int IsFUll(SQQueue* SQ) //判断队列是否为满
  2. {
  3. //尾指针+1追上队头指针,标志队列已经满了
  4. if(((SQ->rear+1)%MAXSIZE == SQ->front)||(SQ->rear==MAXSIZE-2&&SQ->front==-1))
  5. {
  6. return 1;
  7. }
  8. return 0; //队不满
  9. }

4)入队

        在队列不满条件下先将rear+1,再将元素e放在rear指向的位置,因此该操作需要先判断操作合法性,若队列未满,执行相关操作,否则提示并返回0,这里可以调用IsFull(SQQueue* SQ)来判断,代码如下:

  1. int EnterQueue(SQQueue* SQ,ElemType e)
  2. {
  3. if (IsFUll(SQ)) // (SQ->rear + 1)%MAXSIZE == SQ->front
  4. {
  5. printf("队满,不能进队。\n");
  6. return 0;
  7. }
  8. SQ->rear = (SQ->rear + 1) % MAXSIZE;
  9. SQ->data[SQ->rear] = e;
  10. }

5)出队

         这里需要先判断循环队列是否为空,若为空,提示并返回0,若不空则执行相关操作,         先将 SQ->front = (SQ->front+1) % MAXSIZE,再将取出front指向的位置上的元 素并存放于e中,这里可以调用IsEmpty(SQQueue* SQ)来判断,代码如下:

  1. int DeleteQueue(SQQueue* SQ,ElemType* e)
  2. {
  3. if (IsEmpty(SQ))
  4. {
  5. printf("队空,不能出队!\n");
  6. return 0;
  7. }
  8. SQ->front = (SQ->front+1) % MAXSIZE;
  9. *e = SQ->data[SQ->front];
  10. }

6)求队列长度

代码如下:

  1. int lenghtSQQueue(SQQueue* SQ)
  2. {
  3. int len;
  4. len = 0;
  5. len = (SQ->rear-SQ->front+MAXSIZE)%MAXSIZE;
  6. return len;
  7. }

7)打印队列中的元素

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

  1. //打印队列中的与元素
  2. void DispSQQueue(SQQueue* SQ)
  3. {
  4. if (IsEmpty(SQ))
  5. {
  6. printf("队空!");
  7. }
  8. int i;
  9. i = SQ->front+1;
  10. printf("队列元素为:");
  11. while(i <= SQ->rear)
  12. {
  13. printf("%d ",SQ->data[i]);
  14. i++;
  15. }
  16. }

下面是入队、出栈和返回队列长度以及打印出队列元素的操作:

  1. int main()
  2. {
  3. SQQueue SQ;
  4. ElemType e;
  5. InitQueue(&SQ);
  6. //入队
  7. EnterQueue(&SQ,1);
  8. EnterQueue(&SQ,2);
  9. EnterQueue(&SQ,3);
  10. EnterQueue(&SQ,4);
  11. EnterQueue(&SQ,5);
  12. EnterQueue(&SQ,6);
  13. EnterQueue(&SQ,7);
  14. EnterQueue(&SQ,8);
  15. EnterQueue(&SQ,9);
  16. EnterQueue(&SQ,10);
  17. //打印队列元素
  18. DispSQQueue(&SQ);
  19. printf("\n");
  20. printf("队列长度为:%d\n",lenghtSQQueue(&SQ));
  21. //出队
  22. DeleteQueue(&SQ,&e);
  23. printf("出队元素为:%d\n",e);
  24. DeleteQueue(&SQ,&e);
  25. printf("出队元素为:%d\n",e);
  26. //打印队列元素
  27. DispSQQueue(&SQ);
  28. printf("\n");
  29. EnterQueue(&SQ,8);
  30. EnterQueue(&SQ,9);
  31. //打印队列元素
  32. DispSQQueue(&SQ);
  33. printf("\n");
  34. EnterQueue(&SQ,10);
  35. printf("队列长度为:%d\n",lenghtSQQueue(&SQ));
  36. return 1;
  37. }

测试结果如下:

 

当元素10进栈时,队满提示,并返回队列元素,在将队首元素出栈两次,返回队列元素,再将元素8,9进队,再返回队列元素,此时再将元素10进队时提示队满,返回队列长度,自此,循环队列构造完成。

最后再附上完整代码:

  1. #include <stdio.h>
  2. #define MAXSIZE 10
  3. typedef int ElemType;
  4. typedef struct
  5. {
  6. ElemType data[MAXSIZE];//存储值
  7. int front;//存储队头元素前一个单元的下标
  8. int rear;//存储队尾元素的下标
  9. }SQQueue;
  10. /*
  11. 初始化:front=-1;rear=-1;
  12. 为了区分空和满,任意时候都预留1个单元出来
  13. x的下一个:(x+1)%MAXSIZE
  14. 空:front==rear
  15. 满:(rear+1)%MAXSIZE==front
  16. 进队:
  17. rear=(rear+1)%MAXSIZE;
  18. data[rear]=e;
  19. 出队:
  20. front=(front+1)%MAXSIZE;
  21. *e=data[front];
  22. 长度:
  23. (rear-front+MAXSIZE)%MAXSIZE
  24. */
  25. /*
  26. 空:q->front==NULL && q->rear==NULL
  27. */
  28. void InitQueue(SQQueue* SQ)
  29. {
  30. SQ->front = SQ->rear = -1;
  31. }
  32. int IsEmpty(SQQueue* SQ) //判断队列是否为空
  33. {
  34. if (SQ->front == SQ->rear)
  35. {
  36. return 1; //队空
  37. }
  38. return 0;
  39. }
  40. int IsFUll(SQQueue* SQ) //判断队列是否为满
  41. {
  42. //尾指针+1追上队头指针,标志队列已经满了
  43. if(((SQ->rear+1)%MAXSIZE == SQ->front)||(SQ->rear==MAXSIZE-2&&SQ->front==-1))
  44. {
  45. return 1;
  46. }
  47. return 0; //队不满
  48. }
  49. int EnterQueue(SQQueue* SQ,ElemType e)
  50. {
  51. if (IsFUll(SQ)) // (SQ->rear + 1)%MAXSIZE == SQ->front
  52. {
  53. printf("队满,不能进队。\n");
  54. return 0;
  55. }
  56. SQ->rear = (SQ->rear + 1) % MAXSIZE;
  57. SQ->data[SQ->rear] = e;
  58. }
  59. int DeleteQueue(SQQueue* SQ,ElemType* e)
  60. {
  61. if (IsEmpty(SQ))
  62. {
  63. printf("队空,不能出队!\n");
  64. return 0;
  65. }
  66. SQ->front = (SQ->front+1) % MAXSIZE;
  67. *e = SQ->data[SQ->front];
  68. }
  69. int lenghtSQQueue(SQQueue* SQ)
  70. {
  71. int len;
  72. len = 0;
  73. len = (SQ->rear-SQ->front+MAXSIZE)%MAXSIZE;
  74. return len;
  75. }
  76. void DispSQQueue(SQQueue* SQ)
  77. {
  78. int index;
  79. int i;
  80. i = 1;
  81. index=(SQ->front+1)%MAXSIZE;
  82. printf("队列元素为:");
  83. while(i <= lenghtSQQueue(SQ))
  84. {
  85. printf("%d ",SQ->data[index]);
  86. index=(index+1)%MAXSIZE;
  87. i++;
  88. }
  89. }
  90. int main()
  91. {
  92. SQQueue SQ;
  93. ElemType e;
  94. InitQueue(&SQ);
  95. //入队
  96. EnterQueue(&SQ,1);
  97. EnterQueue(&SQ,2);
  98. EnterQueue(&SQ,3);
  99. EnterQueue(&SQ,4);
  100. EnterQueue(&SQ,5);
  101. EnterQueue(&SQ,6);
  102. EnterQueue(&SQ,7);
  103. EnterQueue(&SQ,8);
  104. EnterQueue(&SQ,9);
  105. EnterQueue(&SQ,10);
  106. //打印队列元素
  107. DispSQQueue(&SQ);
  108. printf("\n");
  109. printf("队列长度为:%d\n",lenghtSQQueue(&SQ));
  110. //出队
  111. DeleteQueue(&SQ,&e);
  112. printf("出队元素为:%d\n",e);
  113. DeleteQueue(&SQ,&e);
  114. printf("出队元素为:%d\n",e);
  115. //打印队列元素
  116. DispSQQueue(&SQ);
  117. printf("\n");
  118. EnterQueue(&SQ,8);
  119. EnterQueue(&SQ,9);
  120. //打印队列元素
  121. DispSQQueue(&SQ);
  122. printf("\n");
  123. EnterQueue(&SQ,10);
  124. printf("队列长度为:%d\n",lenghtSQQueue(&SQ));
  125. return 1;
  126. }

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

闽ICP备14008679号