当前位置:   article > 正文

队列的基本操作——常见队列的对比分析(c语言完整代码包含注释)_c语言获取队列长度

c语言获取队列长度

目录

一、队列

1.1基本概念

1.2基本操作

1.3 队列分类

1.3.1带头队列

1.3.2不带头队列

1.3.3 循环带头队列

1.3.4 循环不带头队列

1.3.5 总结

二、代码实现

2.1带头队列

2.2不带头队列

2.3循环带头队列

2.4循环不带头队列


一、队列

1.1基本概念

        队列(Queue)是一种常见的数据结构,它遵循先进先出(First In First Out, FIFO)的原则,类似于现实生活中排队等待的概念。在队列中,元素按照其插入的顺序排列,最先插入的元素将最先被移除。

  • 队列元素:队列中的每个元素称为一个队列元素,可以是任意类型的数据。
  • 队列头(front):队列的头部,即第一个元素所在的位置,通常用于删除元素操作。
  • 队列尾(rear):队列的尾部,即最后一个元素所在的位置,通常用于插入元素操作。

1.2基本操作

        队列的基本操作主要包括入队和出队两种操作,通过这两种操作可以实现对队列中元素的添加和移除。在使用队列时,需要注意保持操作的顺序,遵循 FIFO 的规则,以确保队列的正确性和有效性。

  • 入队(enqueue):将元素插入到队列的末尾,即在队尾添加一个新元素。

  • 出队(dequeue):从队列的头部移除一个元素,并返回该元素的值。

  • 判空(isEmpty):判断队列是否为空,即队列中是否有元素。

  • 判满(isFull):判断队列是否已满,即队列中的元素数量是否达到上限。

  • 获取队头元素(peek):查看队列头部的元素值,但不移除该元素。

  • 清空队列(clear):移除队列中的所有元素,使队列变为空队列。

  • 获取队列长度(size):返回队列中元素的数量。

1.3 队列分类

1.3.1带头队列

  • front 和 rear 的初始值:在带头的队列中,front 和 rear 的初始值通常都设置为 0,表示头结点的位置。
  • 插入元素:在带头的队列中,插入元素时,先将 rear 加一,再将元素插入到 rear 所指向的位置。
  • 删除元素:在带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。

1.3.2不带头队列

  • front 和 rear 的初始值:通常情况下,不带头的队列中,front 和 rear 的初始值都为 -1,表示队列为空。
  • 插入元素:在不带头的队列中,插入元素时,先将 rear 加一,再将元素插入到 rear 所指向的位置。
  • 删除元素:在不带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。

1.3.3 循环带头队列

  • front 和 rear 的初始值:通常情况下,front 和 rear 的初始值都为 0,表示队列为空。
  • 插入元素:先将 rear 加一,再将元素插入到 rear 所指向的位置。如果 rear 达到数组末尾,可以通过取余运算将 rear 置为 0,实现循环利用数组空间。
  • 删除元素:先将 front 加一,返回 front 指向的位置的元素。同样地,如果 front 达到数组末尾,可通过取余运算将 front 置为 0。
  • 判空条件:当 front 和 rear 的值相等时,表示队列为空。
  • 判满条件:当 (rear + 1) % 数组长度 等于 front 的值时,表示队列满。

1.3.4 循环不带头队列

  • front 和 rear 的初始值:通常情况下,front 和 rear 的初始值都为 -1,表示队列为空。
  • 插入元素:先将 rear 加一,再将元素插入到 rear 所指向的位置。如果 rear 达到数组末尾,可以通过取余运算将 rear 置为 0,实现循环利用数组空间。
  • 删除元素:在不带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。
  • 判空条件:当 front 和 rear 的值相等且等于 -1 时,表示队列为空。
  • 判满条件:当 (rear + 1) % 数组长度 等于 front 的值时,表示队列满。

1.3.5 总结

        总的来说,循环队列带头和不带头在判满和判空上的逻辑是相同的,都是根据指针的位置关系来判断队列状态;而引入头结点的主要作用是简化队列为空和队列满的判断逻辑,使队列操作更加灵活高效。

二、代码实现

2.1带头队列

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define SIZE 5
  4. // 定义一个Queue结构体表示队列
  5. typedef struct {
  6. int items[SIZE];
  7. int front; // 队列头指针,指向头结点
  8. int rear; // 队列尾指针,指向最后一个元素
  9. } Queue;
  10. // 创建一个空队列并返回其指针
  11. Queue* createQueue() {
  12. Queue *queue = (Queue*)malloc(sizeof(Queue)); // 为队列分配内存
  13. queue->front = 0; // 初始化队列头指针
  14. queue->rear = 0; // 初始化队列尾指针
  15. return queue;
  16. }
  17. // 判断队列是否满了
  18. int isFull(Queue *queue) {
  19. return (queue->rear == SIZE); // 如果队列尾指针指向最后一个元素的下一个位置,则队列已满
  20. }
  21. // 判断队列是否为空
  22. int isEmpty(Queue *queue) {
  23. return (queue->front == queue->rear); // 如果队列头指针和尾指针相等,说明队列为空
  24. }
  25. // 将元素添加到队列尾部
  26. void enqueue(Queue *queue, int item) {
  27. if (isFull(queue)) { // 如果队列已满,打印提示信息
  28. printf("队列已满,无法入队。\n");
  29. } else {
  30. queue->rear++; // 队列尾指针加1
  31. queue->items[queue->rear - 1] = item; // 将元素存储到队列尾部
  32. printf("%d 入队成功。\n", item); // 打印添加成功信息
  33. }
  34. }
  35. // 从队列头部移除一个元素并返回其值
  36. int dequeue(Queue *queue) {
  37. int item;
  38. if (isEmpty(queue)) { // 如果队列为空,打印提示信息并返回-1表示操作失败
  39. printf("队列为空,无法出队。\n");
  40. return -1;
  41. } else {
  42. item = queue->items[queue->front]; // 获取队列头部元素的值
  43. queue->front++; // 队列头指针加1
  44. printf("%d 出队成功。\n", item); // 打印移除成功信息
  45. return item; // 返回移除的元素值
  46. }
  47. }
  48. int main() {
  49. Queue *queue = createQueue(); // 创建一个新的队列并获取其指针
  50. // 进行入队列和出队列操作
  51. enqueue(queue, 10);
  52. enqueue(queue, 20);
  53. enqueue(queue, 30);
  54. dequeue(queue);
  55. dequeue(queue);
  56. dequeue(queue);
  57. dequeue(queue); // 尝试从空队列中出队列
  58. free(queue); // 释放队列内存空间
  59. return 0;
  60. }

2.2不带头队列

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define SIZE 5
  4. // 定义一个Queue结构体表示队列
  5. typedef struct {
  6. int items[SIZE]; // 存储队列元素的数组
  7. int front; // 队列头指针
  8. int rear; // 队列尾指针
  9. } Queue;
  10. // 创建一个空队列并返回其指针
  11. Queue* createQueue() {
  12. Queue *queue = (Queue*)malloc(sizeof(Queue)); // 为队列分配内存
  13. queue->front = -1; // 初始化队列头指针
  14. queue->rear = -1; // 初始化队列尾指针
  15. return queue;
  16. }
  17. // 判断队列是否满了
  18. int isFull(Queue *queue) {
  19. return (queue->rear == SIZE - 1); // 如果队列尾指针指向最后一个元素,则队列已满
  20. }
  21. // 判断队列是否为空
  22. int isEmpty(Queue *queue) {
  23. return (queue->front == -1 || queue->front > queue->rear); // 如果队列头指针指向了最后一个元素(队列为空),或指向的元素已经被出队列了,说明队列为空
  24. }
  25. // 将元素添加到队列尾部
  26. void enqueue(Queue *queue, int item) {
  27. if (isFull(queue)) { // 如果队列已满,打印提示信息
  28. printf("队列已满,无法入队。\n");
  29. } else {
  30. if (queue->front == -1) { // 如果队列为空,将队列头指针设置为0
  31. queue->front = 0;
  32. }
  33. queue->rear++; // 队列尾指针加1
  34. queue->items[queue->rear] = item; // 将元素存储到队列尾部
  35. printf("%d 入队成功。\n", item); // 打印添加成功信息
  36. }
  37. }
  38. // 从队列头部移除一个元素并返回其值
  39. int dequeue(Queue *queue) {
  40. int item;
  41. if (isEmpty(queue)) { // 如果队列为空,打印提示信息并返回-1表示操作失败
  42. printf("队列为空,无法出队。\n");
  43. return -1;
  44. } else {
  45. item = queue->items[queue->front]; // 获取队列头部元素的值
  46. queue->front++; // 队列头指针加1
  47. printf("%d 出队成功。\n", item); // 打印移除成功信息
  48. return item; // 返回移除的元素值
  49. }
  50. }
  51. int main() {
  52. Queue *queue = createQueue(); // 创建一个新的队列并获取其指针
  53. // 进行入队列和出队列操作
  54. enqueue(queue, 10);
  55. enqueue(queue, 20);
  56. enqueue(queue, 30);
  57. dequeue(queue);
  58. dequeue(queue);
  59. dequeue(queue);
  60. dequeue(queue); // 尝试从空队列中出队列
  61. free(queue); // 释放队列内存空间
  62. return 0;
  63. }

2.3循环带头队列

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX_SIZE 4 // 队列的最大容量,带头
  4. // 循环队列结构体
  5. typedef struct {
  6. int data[MAX_SIZE]; // 用数组存储队列元素
  7. int front; // 队头指针
  8. int rear; // 队尾指针
  9. } CircularQueue;
  10. // 初始化循环队列
  11. void initQueue(CircularQueue *queue) {
  12. queue->front = 0; // 初始时队头指针指向第一个元素
  13. queue->rear = 0; // 初始时队尾指针指向第一个元素
  14. }
  15. // 判断队列是否为空
  16. int isEmpty(CircularQueue *queue) {
  17. return queue->front == queue->rear; // 队列为空时,队头指针与队尾指针相等
  18. }
  19. // 判断队列是否已满
  20. int isFull(CircularQueue *queue) {
  21. return (queue->rear + 1) % MAX_SIZE == queue->front; // 队列已满时,队尾指针的下一个位置为队头指针
  22. }
  23. // 入队操作
  24. void enqueue(CircularQueue *queue, int item) {
  25. if (isFull(queue)) { // 判断队列是否已满
  26. printf("队列已满,无法插入新元素\n");
  27. } else {
  28. queue->data[queue->rear] = item; // 将新元素插入队尾
  29. queue->rear = (queue->rear + 1) % MAX_SIZE; // 移动队尾指针的位置
  30. printf("入队成功: %d\n", item);
  31. }
  32. }
  33. // 出队操作
  34. int dequeue(CircularQueue *queue) {
  35. int item;
  36. if (isEmpty(queue)) { // 判断队列是否为空
  37. printf("队列为空,无法出队\n");
  38. return -1;
  39. } else {
  40. item = queue->data[queue->front]; // 取出队头元素
  41. queue->front = (queue->front + 1) % MAX_SIZE; // 移动队头指针的位置
  42. printf("出队元素: %d\n", item);
  43. return item;
  44. }
  45. }
  46. // 主函数
  47. int main() {
  48. CircularQueue queue;
  49. initQueue(&queue); // 初始化循环队列
  50. enqueue(&queue, 1); // 入队操作
  51. enqueue(&queue, 2);
  52. enqueue(&queue, 3);
  53. enqueue(&queue, 3);
  54. dequeue(&queue); // 出队操作
  55. dequeue(&queue);
  56. dequeue(&queue);
  57. dequeue(&queue);
  58. return 0;
  59. }

2.4循环不带头队列

  1. #include <stdio.h>
  2. #define MAX_SIZE 5
  3. // 定义循环队列结构体,不带头
  4. typedef struct {
  5. int data[MAX_SIZE]; // 用数组存储队列元素
  6. int front; // 队头指针
  7. int rear; // 队尾指针
  8. } CircularQueue;
  9. // 初始化循环队列
  10. void initQueue(CircularQueue *queue) {
  11. queue->front = -1;
  12. queue->rear = -1;
  13. }
  14. // 判断队列是否为空
  15. int isEmpty(CircularQueue *queue) {
  16. return (queue->front == -1 && queue->rear == -1);
  17. }
  18. // 判断队列是否已满
  19. int isFull(CircularQueue *queue) {
  20. return ((queue->rear + 1) % MAX_SIZE == queue->front);
  21. }
  22. // 入队操作
  23. void enqueue(CircularQueue *queue, int value) {
  24. if (isFull(queue)) {
  25. printf("队列已满,无法入队。\n");
  26. } else if (isEmpty(queue)) {
  27. queue->front = 0;
  28. queue->rear = 0;
  29. queue->data[queue->rear] = value;
  30. printf("%d 入队成功。\n", value);
  31. } else {
  32. queue->rear = (queue->rear + 1) % MAX_SIZE;
  33. queue->data[queue->rear] = value;
  34. printf("%d 入队成功。\n", value);
  35. }
  36. }
  37. // 出队操作
  38. int dequeue(CircularQueue *queue) {
  39. if (isEmpty(queue)) {
  40. printf("队列为空,无法出队。\n");
  41. return -1;
  42. } else {
  43. int value = queue->data[queue->front];
  44. if (queue->front == queue->rear) {
  45. queue->front = -1;
  46. queue->rear = -1;
  47. } else {
  48. queue->front = (queue->front + 1) % MAX_SIZE;
  49. }
  50. printf("%d 出队成功。\n", value);
  51. return value;
  52. }
  53. }
  54. int main() {
  55. CircularQueue queue;
  56. initQueue(&queue);
  57. // 入队操作
  58. enqueue(&queue, 10);
  59. enqueue(&queue, 20);
  60. enqueue(&queue, 30);
  61. enqueue(&queue, 40);
  62. enqueue(&queue, 50);
  63. enqueue(&queue, 60); // 队列已满,无法入队
  64. // 出队操作
  65. dequeue(&queue);
  66. dequeue(&queue);
  67. dequeue(&queue);
  68. dequeue(&queue);
  69. dequeue(&queue);
  70. dequeue(&queue); // 队列已空,无法出队
  71. return 0;
  72. }

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

闽ICP备14008679号