当前位置:   article > 正文

C++数据结构:普通队列与循环队列_循环队列和普通队列的区别

循环队列和普通队列的区别

什么是队列?

       队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构。

队列分类

      普通队列与循环队列,普通队列可以看做是一列数据,环形队列可以看做是一个圆,当普通队列的数据索引可以循环设置时,普通队列就成了循环队列。这两种都可以用数组来实现。

循环队列的C++实现

       下面说明用数组实现循环队列的方法

     (1)队头和队尾都是0位置,从队尾插入,队头取数据。

     (2)插入数据:每次插入数据时,先判断队列是否是满的。在队列未满时,从队尾插入数据,队尾移向下一个位置。在队列满了时,如果要再插入数据,此时就得把队头数据弹出,队头指向下一个位置,再从队尾插入。

     (3)取数据,从队头取。

  示例代码:

  头文件

  1. /*
  2. 环形队列
  3. 用数组模拟环形队列的实现
  4. */
  5. #pragma once
  6. class CircularQueue
  7. {
  8. public:
  9. CircularQueue(int capcity);
  10. ~CircularQueue();
  11. int getQueueLength() const;
  12. bool isEmpty();
  13. bool isFull();
  14. void Clear();
  15. void Push(int data); //插入新元素,队尾插
  16. int Pop(); //弹出首元素
  17. void Print();
  18. private:
  19. int *m_pCirQueue; //存放队列数据的数组容器
  20. int m_iCapacity; //队列容量
  21. int m_iLength; //队列长度
  22. int m_iHead; //队列头索引
  23. int m_iTail; //队列尾部索引
  24. };

cpp文件

  1. #include "CircularQueue.h"
  2. #include <iostream>
  3. using namespace std;
  4. CircularQueue::CircularQueue(int capcity)
  5. {
  6. m_iCapacity = capcity;
  7. m_iHead = 0;
  8. m_iTail = 0;
  9. m_iLength = 0;
  10. m_pCirQueue = new int[m_iCapacity];
  11. }
  12. CircularQueue::~CircularQueue()
  13. {
  14. delete[] m_pCirQueue;
  15. }
  16. int CircularQueue::getQueueLength() const
  17. {
  18. return m_iLength;
  19. }
  20. bool CircularQueue::isEmpty()
  21. {
  22. if (m_iLength > 0)
  23. {
  24. return false;
  25. }
  26. return true;
  27. }
  28. bool CircularQueue::isFull()
  29. {
  30. if (m_iLength == m_iCapacity)
  31. {
  32. return true;
  33. }
  34. return false;
  35. }
  36. void CircularQueue::Clear()
  37. {
  38. m_iLength = 0;
  39. m_iHead = 0;
  40. m_iTail = 0;
  41. }
  42. void CircularQueue::Push(int data)
  43. {
  44. if (isFull())
  45. {
  46. Pop();
  47. }
  48. m_pCirQueue[m_iTail] = data;
  49. m_iTail++; //尾部指向下一个位置
  50. m_iTail = m_iTail % m_iCapacity;
  51. m_iLength++;
  52. }
  53. int CircularQueue::Pop()
  54. {
  55. if (isEmpty())
  56. {
  57. return false;
  58. }
  59. int pop = m_pCirQueue[m_iHead];
  60. m_iHead++;
  61. m_iHead = m_iHead % m_iCapacity;
  62. m_iLength--;
  63. return pop;
  64. }
  65. //遍历循环队列
  66. void CircularQueue::Print()
  67. {
  68. for (int i = m_iHead; i < m_iHead + m_iLength; i++)
  69. {
  70. cout << m_pCirQueue[i % m_iCapacity] << " ";
  71. }
  72. cout << endl;
  73. }

main.cpp测试循环队列的功能

  1. #include <iostream>
  2. #include "CircularQueue.h"
  3. using namespace std;
  4. int main()
  5. {
  6. CircularQueue *pQueue = new CircularQueue(4);
  7. pQueue->Push(2);
  8. pQueue->Push(4);
  9. pQueue->Push(6);
  10. pQueue->Push(8);
  11. pQueue->Push(9);
  12. cout << "遍历队列" << endl;
  13. pQueue->Print();
  14. pQueue->Pop();
  15. cout << "遍历队列" << endl;
  16. pQueue->Print();
  17. system("pause");
  18. return 0;
  19. }

运行结果:

模板队列的实现

       上面是用的int数组作为队列容器,我们可以用模板对其改造,代码如下,新建一个模板队列类TCircularQueue, 代码如下:

       TCircularQueue.h

  1. #pragma once
  2. template<typename T>
  3. class TCircularQueue
  4. {
  5. public:
  6. TCircularQueue(int capacity = 10);
  7. ~TCircularQueue();
  8. int getQueueLength() const;
  9. bool isEmpty();
  10. bool isFull();
  11. void Clear();
  12. void Push(T data); //插入新元素,队尾插
  13. T Pop(); //弹出首元素
  14. T* Print();
  15. private:
  16. T *m_pCirQueue; //存放队列数据的数组容器
  17. int m_iCapacity; //队列容量
  18. int m_iLength; //队列长度
  19. int m_iHead; //队列头索引
  20. int m_iTail; //队列尾部索引
  21. };
  22. template<typename T>
  23. TCircularQueue<T>::TCircularQueue(int capacity)
  24. {
  25. m_iCapacity = capacity;
  26. m_iHead = 0;
  27. m_iTail = 0;
  28. m_iLength = 0;
  29. m_pCirQueue = new T[m_iCapacity];
  30. }
  31. template<typename T>
  32. TCircularQueue<T>::~TCircularQueue()
  33. {
  34. delete[] m_pCirQueue;
  35. }
  36. template<typename T>
  37. int TCircularQueue<T>::getQueueLength() const
  38. {
  39. return m_iLength;
  40. }
  41. template<typename T>
  42. bool TCircularQueue<T>::isEmpty()
  43. {
  44. if (m_iLength > 0)
  45. {
  46. return false;
  47. }
  48. return true;
  49. }
  50. template<typename T>
  51. bool TCircularQueue<T>::isFull()
  52. {
  53. if (m_iLength == m_iCapacity)
  54. {
  55. return true;
  56. }
  57. return false;
  58. }
  59. template<typename T>
  60. void TCircularQueue<T>::Clear()
  61. {
  62. m_iLength = 0;
  63. m_iHead = 0;
  64. m_iTail = 0;
  65. }
  66. template<typename T>
  67. void TCircularQueue<T>::Push(T data)
  68. {
  69. if (isFull())
  70. {
  71. Pop();
  72. }
  73. m_pCirQueue[m_iTail] = data;
  74. m_iTail++; //尾部指向下一个位置
  75. m_iTail = m_iTail % m_iCapacity;
  76. m_iLength++;
  77. }
  78. template<typename T>
  79. T TCircularQueue<T>::Pop()
  80. {
  81. T pop;
  82. if (isEmpty())
  83. {
  84. return pop;
  85. }
  86. pop = m_pCirQueue[m_iHead];
  87. m_iHead++;
  88. m_iHead = m_iHead % m_iCapacity;
  89. m_iLength--;
  90. return pop;
  91. }
  92. //遍历循环队列
  93. template<typename T>
  94. T* TCircularQueue<T>::Print()
  95. {
  96. T *p = NULL;
  97. if (m_iLength > 0)
  98. {
  99. p = new T[m_iLength];
  100. for (int i = m_iHead, j = 0; i < m_iHead + m_iLength, j < m_iLength; i++, j++)
  101. {
  102. //cout << m_pCirQueue[i % m_iCapacity] << " ";
  103. p[j] = m_pCirQueue[i % m_iCapacity];
  104. }
  105. }
  106. return p;
  107. }

     在新建一个Student类作为模板数据

     .h

  1. #pragma once
  2. #include<iostream>
  3. #include<string>
  4. using namespace std;
  5. class Student
  6. {
  7. public:
  8. Student(string name = "", int age = 10);
  9. void Print();
  10. private:
  11. string m_name;
  12. int m_iAge;
  13. };

    .cpp

  1. #include "Student.h"
  2. Student::Student(string name, int age)
  3. {
  4. m_name = name;
  5. m_iAge = age;
  6. }
  7. void Student::Print()
  8. {
  9. cout << "name = " << m_name << " age = " << m_iAge << endl;
  10. }

    测试代码:

  1. #include <iostream>
  2. #include "TCircularQueue.h"
  3. #include "Student.h"
  4. using namespace std;
  5. int main()
  6. {
  7. TCircularQueue<Student> *pQueue = new TCircularQueue<Student>(4);
  8. Student st1("鲁班", 13);
  9. Student st2("后裔", 400);
  10. Student st3("安其拉", 14);
  11. Student st4("甄姬", 25);
  12. Student st5("妲己", 19);
  13. Student st6("亚瑟", 78);
  14. pQueue->Push(st1);
  15. pQueue->Push(st2);
  16. pQueue->Push(st3);
  17. pQueue->Push(st4);
  18. pQueue->Push(st5);
  19. pQueue->Push(st6);
  20. int leng = pQueue->getQueueLength();
  21. cout << "leng = " << leng << endl;
  22. Student *p = new Student[leng];
  23. cout << "遍历队列" << endl;
  24. p = pQueue->Print();
  25. for (int i = 0; i < leng; i++)
  26. {
  27. p[i].Print();
  28. }
  29. delete pQueue;
  30. system("pause");
  31. return 0;
  32. }

      运行结果

      队列在开发中应用的很多,比如线程池,音视频同步等。

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

闽ICP备14008679号