• C/C++数据结构——队列


    个人主页仍有未知等待探索_C语言疑难,数据结构,小项目-CSDN博客

    专题分栏:数据结构_仍有未知等待探索的博客-CSDN博客

    目录

    一、前言

    二、队列的基本操作(循环队)

    1、循环队的数据类型

    2、循环队的名词解释

    3、循环队的创建及其初始化

    第一种写法  

    第二种写法 

    4、 判断队满

    5、判断队空

    6、入队 

    7、出队

     8、求长度

    三、优势

    四、总代码


    一、前言

    在前面学习了栈的基本知识,知道栈是一种特殊的线性表,其特点是先进后出。

    而接下来要学的队列也是一种操作受限的线性表,其特点是先进先出。从队头出队,从队尾入队。

    二、队列的基本操作(循环队)

    1、循环队的数据类型

    在下面的数据类型实现中,存数据的data数组的类型有两种写法。

    第一种写法:这样写的话,数组是固定的MAX大小。

    1. //第一种写法
    2. elemtype data[MAX];

    第二种写法:这样写的话,可以通过动态内存开辟来给data开辟足够大的空间。 

    1. //第二种写法
    2. elemtype* data;

    front和rear的作用是记录对头位置和队尾位置。 

    由下图可以清晰的看出:

    front:指向第一个元素。

    rear:指向最后一个元素的下一个元素。

    1. #define MAX 100
    2. typedef int elemtype;
    3. typedef struct Queue
    4. {
    5. //第一种写法
    6. //elemtype data[MAX];//elemtype是为了改data的数据类型的时候方便
    7. //第二种写法
    8. elemtype* data;
    9. int front;//队首指针
    10. int rear;//队尾指针
    11. }Queue;

    2、循环队的名词解释

    可能大家一开始都会有疑问,为什么叫做循环队呢?栈用数组进行存储叫做顺序栈,为什么队列用数组存储叫做循环队呢?

    假设这是一个队列(并且装满了,一般队列填数组会空一个元素位置)。

    如果进行一次出队操作。

     如果要进行一次入队操作的话,现在只有下标为0的地方有空,但是现在rear指向的是最后一个元素的下一个元素。如果rear继续+1,往下走的话,数组会越界,只有让rear指向下标为零的位置上。

    3、循环队的创建及其初始化

    第一种写法  

    1. 创建循环队和创建栈的操作大体相同,都是用malloc进行开辟空间,如果失败,则返回空。
    2. 在对front指针和rear指针进行初始化的时候,将他们赋值为0就完成了操作。(这里说的指针是泛称,不是真的指针类型,而是有着和指针相同的作用,都用来记录位置
    1. #include
    2. #include
    3. #define MAX 100
    4. typedef int elemtype;
    5. typedef struct Queue
    6. {
    7. //第一种写法
    8. elemtype data[MAX];//elemtype是为了改data的数据类型的时候方便
    9. int front;//队首指针
    10. int rear;//队尾指针
    11. }Queue;
    12. Queue* CreateQueue();
    13. int main()
    14. {
    15. Queue* Q = CreateQueue();
    16. if (Q == NULL)//如果Q开辟失败,结束程序
    17. {
    18. return 0;
    19. }
    20. return 0;
    21. }
    22. Queue* CreateQueue()
    23. {
    24. Queue* Q = (Queue*)malloc(sizeof(Queue));
    25. if (Q == NULL)
    26. {
    27. perror("malloc");//写出错误原因
    28. return NULL;//如果Q开辟失败,提前结束
    29. }
    30. Q->front = 0;
    31. Q->rear = 0;
    32. return Q;
    33. }

    第二种写法 

     大体上和第一种写法没什么区别,唯一不同的是还要在给数组data开辟空间

    1. #include
    2. #include
    3. #define MAX 100
    4. typedef int elemtype;
    5. typedef struct Queue
    6. {
    7. //第二种写法
    8. elemtype* data;
    9. int front;//队首指针
    10. int rear;//队尾指针
    11. }Queue;
    12. Queue* CreateQueue();
    13. int main()
    14. {
    15. Queue* Q = CreateQueue();
    16. if (Q == NULL)
    17. {
    18. return 0;
    19. }
    20. return 0;
    21. }
    22. Queue* CreateQueue()
    23. {
    24. Queue* Q = (Queue*)malloc(sizeof(Queue));
    25. if (Q == NULL)
    26. {
    27. perror("malloc_Q");
    28. return NULL;
    29. }
    30. Q->data = (elemtype*)malloc(MAX * sizeof(elemtype));
    31. if(Q->data==NULL)
    32. {
    33. perror("malloc_Q->data");
    34. return NULL;
    35. }
    36. Q->front = 0;
    37. Q->rear = 0;
    38. return Q;
    39. }

    4、 判断队满

    当Q->front == (Q->rear + 1) % MAX的时候,队满。

    Q->front=0,Q->rear=6,将这数据带入上述式子,可得出队满结论,和实际符合。其中主要取循环作用的是取余号(%)

    当队满的时候返回1,不满返回0。

    1. int IsFull(Queue* Q)
    2. {
    3. if (Q->front == (Q->rear + 1) % MAX)
    4. return 1;
    5. return 0;
    6. }

    5、判断队空

    当Q->front == Q->rear的时候,队空。

    当对空的时候返回1,否则返回0。

    1. int IsEmpty(Queue* Q)
    2. {
    3. if (Q->front == Q->rear)
    4. return 1;
    5. return 0;
    6. }

    6、入队 

    注意: Q->rear = (Q->rear + 1) % MAX

    1. int Push(Queue* Q, elemtype x)
    2. {
    3. if (IsFull(Q))
    4. {
    5. return 0;
    6. }
    7. Q->data[Q->rear] = x;
    8. Q->rear = (Q->rear + 1) % MAX;
    9. return 1;
    10. }

    7、出队

    注意: Q->front= (Q->front + 1) % MAX

    1. int Pop(Queue* Q, elemtype* x)
    2. {
    3. if (IsEmpty(Q))
    4. {
    5. return 0;
    6. }
    7. *x = Q->data[Q->front];
    8. Q->front = (Q->front + 1) % MAX;
    9. return 1;
    10. }

     8、求长度

    注意:有可能Q->rear会在Q->front的左边。

    1. int Queue_length(Queue* Q)
    2. {
    3. return (Q->rear - Q->front + MAX) % MAX;
    4. }

    三、优势

    以上所有的操作的时间复杂度均为O(1) 。

    四、总代码

    1. #include
    2. #include
    3. #define MAX 100
    4. typedef int elemtype;
    5. typedef struct Queue
    6. {
    7. //第一种写法
    8. elemtype data[MAX];//elemtype是为了改data的数据类型的时候方便
    9. int front;//队首指针
    10. int rear;//队尾指针
    11. }Queue;
    12. Queue* CreateQueue();
    13. int IsFull(Queue* Q);
    14. int IsEmpty(Queue* Q);
    15. int Push(Queue* Q, elemtype x);
    16. int Pop(Queue* Q, elemtype* x);
    17. int Queue_length(Queue* Q);
    18. int main()
    19. {
    20. Queue* Q = CreateQueue();
    21. if (Q == NULL)
    22. {
    23. return 0;
    24. }
    25. for (int i = 0; i < 3; i++)
    26. {
    27. int ret = Push(Q, i);
    28. if (ret == 0)
    29. {
    30. printf("队满,入队失败\n");
    31. }
    32. else
    33. {
    34. printf("入队成功\n");
    35. }
    36. }
    37. int x;
    38. int ret = Pop(Q, &x);
    39. if (ret == 0)
    40. {
    41. printf("队空,出队失败\n");
    42. }
    43. else
    44. {
    45. printf("出队成功\n");
    46. }
    47. return 0;
    48. }
    49. Queue* CreateQueue()
    50. {
    51. Queue* Q = (Queue*)malloc(sizeof(Queue));
    52. if (Q == NULL)
    53. {
    54. perror("malloc");
    55. return NULL;
    56. }
    57. Q->front = 0;
    58. Q->rear = 0;
    59. return Q;
    60. }
    61. int IsFull(Queue* Q)
    62. {
    63. if (Q->front == (Q->rear + 1) % MAX)
    64. return 1;
    65. return 0;
    66. }
    67. int IsEmpty(Queue* Q)
    68. {
    69. if (Q->front == Q->rear)
    70. return 1;
    71. return 0;
    72. }
    73. int Push(Queue* Q, elemtype x)
    74. {
    75. if (IsFull(Q))
    76. {
    77. return 0;
    78. }
    79. Q->data[Q->rear] = x;
    80. Q->rear = (Q->rear + 1) % MAX;
    81. return 1;
    82. }
    83. int Pop(Queue* Q, elemtype* x)
    84. {
    85. if (IsEmpty(Q))
    86. {
    87. return 0;
    88. }
    89. *x = Q->data[Q->front];
    90. Q->front = (Q->front + 1) % MAX;
    91. return 1;
    92. }
    93. int Queue_length(Queue* Q)
    94. {
    95. return (Q->rear - Q->front + MAX) % MAX;
    96. }

    谢谢大家的支持!

  • 相关阅读:
    实战:如何编写一个 OpenTelemetry Extensions
    【工作流引擎】Activiti的使用02
    kindle自定义屏保之自定义字帖
    多线程安全的Queue
    二硫键交联的巯基化壳聚糖水凝胶/pH、离子强度敏感性的壳聚糖水凝胶CS-GA-ASP
    Spring(完整版)
    labelme自动标注工具
    解开MongoDB之谜
    使用seldom编写http接口用例
    Spring Boot框架下实现Excel服务端导入导出
  • 原文地址:https://blog.csdn.net/qq_73435980/article/details/134005372