当前位置:   article > 正文

【头歌】数据结构-队列的应用_头歌数据结构队列的应用

头歌数据结构队列的应用

 第1关:循环队列

任务描述

本关任务:编写一个循环队列,实现入队、出队操作,判断队空、队满等特殊情况。

相关知识

为了完成本关任务,你需要掌握:1.循环队列定义,2.入队、出队的定义,3.队空、队满的情况。

循环队列定义

循环队列将数组存储区看成是一个首尾相接的环形区域(下图)。当数据存放到尾地址后,下一个地址就跳转到首地址。循环队列定义如下:

 
  1. struct Queue{
  2. int maxSize; // 队列最大长度
  3. int *data; // 数据指针
  4. int front; // 头指针索引
  5. int rear; // 尾指针索引
  6. };

入队出队定义

入队操作:队列未满,在队尾插入一个元素item,使得data[rear+1]=item,若超过存储空间则尾指针索引取模(rear+1)%maxSize

出队操作:队列不空,返回队首元素值data[front],并移除队首元素front+1,若超过存储空间则头指针索引取模(front+1)%maxSize

队空队满情况

初始化创建空队时,令front=rear=0, 其中front指向队首元素,rear指向队尾元素的下一个元素:

  • 当队空时:front==rear
  • 当队满时:front==rear 亦成立

因此只凭等式front==rear无法判断队空还是队满。 一个方法是少用一个元素空间,约定:队列头指针front在队尾指针rear的下一个位置上作为队列“满”状态的标志(如上图),即:

  • 队空时: front==rear
  • 队满时: (rear+1)%maxSize==front

编程要求

本关的编程任务是补全右侧代码片段isFullisEmptyenQueuedeQueueBeginEnd中间的代码,具体要求如下:

  • isFull中,判断队列是否为满,若满返回true并在一行打印The queue is Full,否则返回false
  • isEmpty中,判断队列是否为空,若空返回true并在一行打印The queue is Empty,否则返回false
  • enQueue中,实现入队操作:将元素item加入队列尾部;
  • deQueue中,实现出队操作:移除队列首部元素,并返回元素值。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入: 10 7 enqueue 30 enqueue 98 dequeue enqueue 96 dequeue dequeue enqueue 0 预期输出: 0 The queue is Empty

输入说明: 第一行n m分别表示循环队列大小、入队出队操作记录数量。 接下来m行,enqueue表示入队操作,后面接待入队元素;dequeue表示出队操作。

输出说明: 输出m个操作之后的所有队列元素。


开始你的任务吧,祝你成功!

 

  1. //
  2. // queue_.cpp
  3. // Queue
  4. //
  5. // Created by ljpc on 2018/5/29.
  6. // Copyright © 2018年 ljpc. All rights reserved.
  7. //
  8. #include "queue_.h"
  9. void creatQueue(Queue* que, int maxSize)
  10. // 创建一个循环队列指针que,队列最大长度为maxSize
  11. {
  12. que->maxSize = maxSize;
  13. que->data = (int*)malloc(maxSize * sizeof(int));
  14. que->front = que->rear = 0;
  15. }
  16. void destroyQueue(Queue* que)
  17. // 释放队列内存空间
  18. {
  19. free(que->data);
  20. }
  21. bool isFull(Queue* que)
  22. // 判断队列que是否为满
  23. // 若满返回 true 并在一行打印 The queue is Full 末尾换行!!!
  24. // 否则返回 false
  25. {
  26. // 请在这里补充代码,完成本关任务
  27. /********** Begin *********/
  28. if((que->rear+1)%que->maxSize==que->front)
  29. {
  30. printf("The queue is Full\n");
  31. return true;
  32. }
  33. else return false;
  34. /********** End **********/
  35. }
  36. bool isEmpty(Queue* que)
  37. // 判断队列que是否为空
  38. // 若空返回 true 并在一行打印 The queue is Empty 末尾换行!!!
  39. // 否则返回 false
  40. {
  41. // 请在这里补充代码,完成本关任务
  42. /********** Begin *********/
  43. if(que->rear==que->front)
  44. {
  45. printf("The queue is Empty\n");
  46. return true;
  47. }
  48. else
  49. return false;
  50. /********** End **********/
  51. }
  52. int enQueue(Queue* que, int item)
  53. // 实现入队操作:将元素item加入队列que尾部
  54. // 若队列没满,编写加入操作,返回 1
  55. // 若队列满了,不做任何操作,返回 -1
  56. {
  57. // 请在这里补充代码,完成本关任务
  58. /********** Begin *********/
  59. if(isFull(que))
  60. {
  61. return -1;
  62. }
  63. else
  64. {
  65. que->data[que->rear]=item;
  66. que->rear=(que->rear+1)%que->maxSize;
  67. return 1;
  68. }
  69. /********** End **********/
  70. }
  71. int deQueue(Queue* que)
  72. // 实现出队操作:移除队列que首部元素,并返回元素值
  73. {
  74. // 请在这里补充代码,完成本关任务
  75. /********** Begin *********/
  76. int x;
  77. if(que->front==que->rear)
  78. {
  79. return false;
  80. }
  81. else
  82. {
  83. x=que->data[que->front];
  84. que->front=(que->front+1)%que->maxSize;
  85. }
  86. return x;
  87. /********** End **********/
  88. }
  89. void printQueue(Queue* que)
  90. // 打印队列
  91. {
  92. while (isEmpty(que)==false) {
  93. int item = deQueue(que);
  94. printf("%d ", item);
  95. }
  96. }

 第二关-链队列

任务描述

本关任务:编写一个链队列,实现入队、出队操作,判断队空等特殊情况。

相关知识

为了完成本关任务,你需要掌握:1.链队列定义,2.入队、出队的定义,3.队空的情况。

链队列定义

链队列的定义是在单链表的基础上,增加一个尾指针。队列的特点是“先进先出”,因此只需要一头一尾两个指针,就可以快速地在队头取出数据,在队尾插入数据。

链队列动态创建节点,不需要预设大小,内存空间不需要连续,入队、出队更容易实现。但是存取速度慢,操作也比数组的方式更加复杂。

 
  1. struct Node // 数据节点
  2. {
  3. int data; // 数据类型
  4. Node *next; // 指向下一个节点的指针
  5. };
  6. struct LinkQueue // 链表队列
  7. {
  8. Node *front; // 头指针
  9. Node *rear; // 尾指针
  10. };

入队出队定义

入队操作:

  • 第一步:为待入队元素创建数据节点Node* node
  • 第二步:将队尾节点next指向新节点rear->next = node;
  • 第三步:修改队尾指针rear指向新节点rear = node

出队操作:队列不空,返回队首元素值。

  • 第一步:获取队首节点Node *node = front->next,注意front->next才是指向队列头节点,front本身不具备任何意义。
  • 第二步:移除队首节点,修改front->next = node->next
  • 特殊情况:当队列最后一个元素被删除后,队列尾指针也丢失了,因此需对队尾指针重新赋值,即指向头结点 rear = front

队空情况

初始化创建空队时,令rear = front,即队空的情况是rear == front

编程要求

本关的编程任务是补全右侧代码片段isEmptyenQueuedeQueueBeginEnd中间的代码,具体要求如下:

  • isEmpty中,判断队列是否为空,若空返回true并在一行打印The queue is Empty,否则返回false
  • enQueue中,实现入队操作:将元素item加入队列尾部;
  • deQueue中,实现出队操作:移除队列首部元素,并返回元素值。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入: 7 enqueue 30 enqueue 98 dequeue enqueue 96 dequeue dequeue enqueue 0 预期输出: 0 The queue is Empty

输入说明: 第一行m分别表示链队列入队出队操作记录数量。 接下来m行,enqueue表示入队操作,后面接待入队元素;dequeue表示出队操作。

输出说明: 输出m个操作之后的所有队列元素。


开始你的任务吧,祝你成功!

  1. //
  2. // queue_.cpp
  3. // LinkQueue
  4. //
  5. // Created by ljpc on 2018/5/30.
  6. // Copyright © 2018年 ljpc. All rights reserved.
  7. //
  8. #include "queue_.h"
  9. void creatLinkQueue(LinkQueue* que)
  10. // 创建一个循环队列指针que
  11. {
  12. que->front = (Node*)malloc(sizeof(Node));
  13. que->rear = que->front;
  14. que->rear->next = NULL;
  15. }
  16. bool isEmpty(LinkQueue* que)
  17. // 判断队列que是否为空
  18. // 若空返回 true 并在一行打印 The queue is Empty 末尾换行!!!
  19. // 否则返回 false
  20. {
  21. // 请在这里补充代码,完成本关任务
  22. /********** Begin *********/
  23. if(que->front==que->rear)
  24. {
  25. printf("The queue is Empty\n");
  26. return true;
  27. }
  28. else
  29. return false;
  30. /********** End **********/
  31. }
  32. void enQueue(LinkQueue* que, int item)
  33. // 实现入队操作:将元素item加入队列que尾部
  34. {
  35. // 请在这里补充代码,完成本关任务
  36. /********** Begin *********/
  37. Node *newque=(Node*)malloc(sizeof(Node));
  38. if(newque!=NULL)
  39. {
  40. newque->data=item;
  41. newque->next=NULL;
  42. que->rear->next=newque;
  43. que->rear=newque;
  44. }
  45. /********** End **********/
  46. }
  47. int deQueue(LinkQueue* que)
  48. // 实现出队操作:移除队列que首部元素,并返回元素值
  49. {
  50. // 请在这里补充代码,完成本关任务
  51. /********** Begin *********/
  52. Node *p;
  53. int item;
  54. if(que->front==que->rear)
  55. return false;
  56. p=que->front->next;
  57. que->front->next=p->next;
  58. item=p->data;
  59. if(que->rear==p)
  60. {
  61. que->rear=que->front;
  62. }
  63. free(p);
  64. return item;
  65. /********** End **********/
  66. }
  67. void printQueue(LinkQueue* que)
  68. // 打印队列
  69. {
  70. while (isEmpty(que)==false) {
  71. int item = deQueue(que);
  72. printf("%d ", item);
  73. }
  74. }

第3关:单链表循环队列

任务描述

本关任务:编写一个单链表循环队列,实现入队、出队操作,判断队空等特殊情况。

相关知识

为了完成本关任务,你需要掌握:1.单链表循环队列定义,2.入队、出队的定义,3.队空的情况。

单链表循环队列

单链表循环队列设一个尾指针rear,不设头指针。队尾添加数据的时候,只需要在rearrear->next之间插入该数据节点,然后将rear指向这个节点。因为没有头指针,所以添加一个整形变量size_来判定队列空的情况。

 
  1. struct Node // 数据节点
  2. {
  3. int data; // 数据类型
  4. Node *next; // 指向下一个节点的指针
  5. };
  6. struct CycleQueue // 循环链表队列
  7. {
  8. int size_; // 目前队列元素个数
  9. Node *rear; // 尾指针
  10. };

入队出队定义

注意初始队列时,尾指针rear = NULL以及rear->next = NULL

入队操作:

  • 为待入队元素创建数据节点Node* node
  • 如果队列为空,则尾节点指向新节点rear = noderear->next指向队首节点rear->next = node
  • 如果队列非空,则在rearrear->next之间插入新节点:
     
      
    1. Node *temp = rear->next;
    2. rear->next = node;
    3. node->next = temp;
    4. rear = node;
    5. rear->next = temp;

出队操作:队列不空,返回队首元素值。

  • 第一步:获取队首节点Node *node = rear->next;
  • 第二步:移除队首节点,修改rear->next = node->next

队空情况

队列中不含数据节点,通过变量size_来判定队列空的情况。

编程要求

本关的编程任务是补全右侧代码片段isEmptyenQueuedeQueueBeginEnd中间的代码,具体要求如下:

  • isEmpty中,判断队列是否为空,若空返回true并在一行打印The queue is Empty,否则返回false
  • enQueue中,实现入队操作:将元素item加入队列尾部;
  • deQueue中,实现出队操作:移除队列首部元素,并返回元素值。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入: 7 enqueue 30 enqueue 98 dequeue enqueue 96 dequeue dequeue enqueue 0 预期输出: 0 The queue is Empty

输入说明: 第一行m分别表示链队列入队出队操作记录数量。 接下来m行,enqueue表示入队操作,后面接待入队元素;dequeue表示出队操作。

输出说明: 输出m个操作之后的所有队列元素。


开始你的任务吧,祝你成功!

  1. //
  2. // queue_.cpp
  3. // Cycle
  4. //
  5. // Created by ljpc on 2018/5/30.
  6. // Copyright © 2018年 ljpc. All rights reserved.
  7. //
  8. #include "queue_.h"
  9. void creatCycleQueue(CycleQueue* que)
  10. // 创建一个循环队列指针que
  11. {
  12. que->size_ = 0;
  13. que->rear = NULL;
  14. }
  15. bool isEmpty(CycleQueue* que)
  16. // 判断队列que是否为空
  17. // 若空返回 true 并在一行打印 The queue is Empty 末尾换行!!!
  18. // 否则返回 false
  19. {
  20. // 请在这里补充代码,完成本关任务
  21. /********** Begin *********/
  22. if(que->size_==0){
  23. printf("The queue is Empty\n");
  24. return true;
  25. }else{
  26. return false;
  27. }
  28. /********** End **********/
  29. }
  30. void enQueue(CycleQueue* que, int item)
  31. // 实现入队操作:将元素item加入队列que尾部
  32. {
  33. // 请在这里补充代码,完成本关任务
  34. /********** Begin *********/
  35. Node *newque=(Node*)malloc(sizeof(Node));
  36. newque->data=item;
  37. if(que->size_>0)
  38. {
  39. newque->next=que->rear->next;
  40. que->rear->next=newque;
  41. que->rear=newque;
  42. que->size_++;
  43. }
  44. else
  45. {
  46. que->rear=newque;
  47. que->rear->next=newque;
  48. que->size_++;
  49. }
  50. /********** End **********/
  51. }
  52. int deQueue(CycleQueue* que)
  53. // 实现出队操作:移除队列que首部元素,并返回元素值
  54. {
  55. // 请在这里补充代码,完成本关任务
  56. /********** Begin *********/
  57. Node *p;
  58. int item;
  59. if(isEmpty(que))
  60. return false;
  61. if(que->size_==1)
  62. {
  63. item=que->rear->data;
  64. p=que->rear;
  65. que->rear=NULL;
  66. free(p);
  67. }
  68. else if(que->size_>1)
  69. {
  70. p=que->rear->next;
  71. que->rear->next=p->next;
  72. item=p->data;
  73. free(p);
  74. }
  75. que->size_--;
  76. return item;
  77. /********** End **********/
  78. }
  79. void printQueue(CycleQueue* que)
  80. // 打印队列
  81. {
  82. while (isEmpty(que)==false) {
  83. int item = deQueue(que);
  84. printf("%d ", item);
  85. }
  86. }

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

闽ICP备14008679号