• 【C++】队列来喽,真的很简单的


    我们经历了那么多练习和顺序表,链表,栈的大风大浪,小小一个队列可以说简单至极了

    练习,以及顺序表之类的文章都在我的主页哦,请认真学习之后再看本文

    目录

    1.队列的结构

    2.实现

    3.栈和队列的相互实现


    1.队列的结构

    队列其实就是一种特殊的栈(从结构上来说),他是队头出数据,队尾入数据

     所以有一种很可怕的题目就是栈和队列的相互实现

    2.实现 

    我们还是先学习一下队列的实现吧

    由于用数组实现和栈一样,但是他不像栈,只在一头出入,所以还需要一个结构体来封装他的头指针和尾指针

    1. #include
    2. #include
    3. #include
    4. #include
    5. typedef int type;
    6. typedef struct QlistNode
    7. {
    8. type data;
    9. struct QlistNode* next;
    10. }Q;
    11. typedef struct QNode
    12. {
    13. Q* front;
    14. Q* tail;
    15. int size;
    16. }QL;
    17. void QuenceInit(QL* q);//初始化
    18. void QuencePop(QL* q);//头删
    19. void QuencePush(QL* q, type x);//尾插
    20. bool QEmpty(QL* q);//是否为空
    21. type QFront(QL* q);//获取头部元素
    22. type QBack(QL* q);//获取尾部元素
    23. void QDestory(QL* q);//销毁
    24. int QSize(QL* q);//获取有效元素个数
    25. void QPirnt(QL* q);//打印队列的元素

    实现起来也是没什么区别,只是他的结构内容有点多,不要搞晕

    1. #include "quence.h"
    2. void QuenceInit(QL* q)//初始化
    3. {
    4. assert(q);
    5. q->front = NULL;
    6. q->tail = NULL;
    7. q->size = 0;
    8. }
    9. void QuencePop(QL* q)//头删
    10. {
    11. assert(q);
    12. assert(!QEmpty(q));
    13. if (q->front->next == NULL)
    14. {
    15. free(q->front);
    16. q->front = q->tail = NULL;
    17. }
    18. else
    19. {
    20. Q* cur = q->front;
    21. Q* next = cur->next;
    22. free(cur);
    23. cur = next;
    24. q->front = next;
    25. }
    26. q->size--;
    27. }
    28. void QuencePush(QL* q,type x)//尾插
    29. {
    30. Q* newnode = (Q*)malloc(sizeof(Q));
    31. if (newnode == NULL)
    32. {
    33. perror("malloc fail");
    34. exit(-1);
    35. }
    36. newnode->data = x;
    37. newnode->next = NULL;
    38. if (q->front == NULL && q->tail == NULL)
    39. {
    40. q->front = q->tail = newnode;
    41. }
    42. else
    43. {
    44. q->tail->next = newnode;
    45. q->tail = newnode;
    46. }
    47. q->size++;
    48. }
    49. bool QEmpty(QL* q)//是否为空
    50. {
    51. assert(q);
    52. return q->front == NULL &&q->tail==NULL;
    53. }//空就是1
    54. type QFront(QL* q)//获取头部元素
    55. {
    56. assert(q);
    57. assert(!QEmpty(q));
    58. return q->front->data;
    59. }
    60. type QBack(QL* q)//获取尾部元素
    61. {
    62. assert(q);
    63. assert(!QEmpty(q));
    64. return q->tail->data;
    65. }
    66. void QDestory(QL* q)//销毁
    67. {
    68. assert(q);
    69. Q* cur = q->front;
    70. while (cur)
    71. {
    72. /*Q* next = cur->next;
    73. cur = next;
    74. free(next);*/
    75. Q* del = cur;
    76. cur = cur->next;
    77. free(del);
    78. }
    79. q->front = q->tail = NULL;
    80. q->size = 0;
    81. }
    82. int QSize(QL* q)//获取有效元素个数
    83. {
    84. assert(q);
    85. return q->size;
    86. }
    87. void QPirnt(QL* q)//打印队列的元素
    88. {
    89. assert(q);
    90. Q* cur = q->front;
    91. while (cur)
    92. {
    93. printf("%d ", cur->data);
    94. cur = cur->next;
    95. }
    96. printf("\n");
    97. }

    3.栈和队列的相互实现

    队列实现栈

    队列——》栈

    基于队列一侧出 一侧入的特点,要想变成栈

    当push 1 2 3 4

    在pop的时候就应该先pop 4  因为栈先入的后出

    所以队列的push还是保留没问题

    但是pop就需要把有数据的那个队列除了最后一个元素都转移到空队列里面

     

     由于我们使用C的方法写,所以前面要加上刚才的队列实现

    1. typedef struct {
    2. QL q1;
    3. QL q2;
    4. } MyStack;
    5. MyStack* myStackCreate() {
    6. MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
    7. QuenceInit(&(obj->q1));
    8. QuenceInit(&(obj->q2));
    9. return obj;
    10. }
    11. void myStackPush(MyStack* obj, int x) {
    12. //直接尾插
    13. if(!QEmpty(&obj->q1))
    14. {
    15. QuencePush(&obj->q1,x);
    16. }
    17. else{
    18. QuencePush(&obj->q2,x);
    19. }
    20. }
    21. int myStackPop(MyStack* obj) {
    22. QL *empty=&obj->q1;
    23. QL *nonempty=&obj->q2;
    24. if(!QEmpty(&obj->q1)) //假设错误,实际q1非空
    25. {
    26. empty=&obj->q2;
    27. nonempty=&obj->q1;
    28. }
    29. while(QSize(nonempty)>1)
    30. {
    31. QuencePush(empty,QFront(nonempty));
    32. QuencePop(nonempty);
    33. }
    34. int top=QFront(nonempty);
    35. QuencePop(nonempty);
    36. return top;
    37. }
    38. int myStackTop(MyStack* obj) {
    39. if(!QEmpty(&obj->q1))
    40. {
    41. return QBack(&obj->q1);
    42. }
    43. else{
    44. return QBack(&obj->q2);
    45. }
    46. }
    47. bool myStackEmpty(MyStack* obj) {//两个队列都是空的
    48. return QEmpty(&obj->q1)&&QEmpty(&obj->q2);
    49. }
    50. void myStackFree(MyStack* obj) {
    51. QDestory(&obj->q1);
    52. QDestory(&(obj->q2));
    53. free(obj);
    54. }

    栈实现队列

    栈——>队列

    当我们push 1 2 3 4

    最后要实现队列,所以应该先pop 1 

    所以还是栈的压数据可以保留,但是pop需要变一变

     

     我们发现,如果还是之前的思路乱套了,1确实是没了,但是相同的办法2就删不掉了,下一个删的就是4,显然不对

    新思路就是定义一个push栈和pop栈

    在pop的时候先拿走pop栈的栈顶元素此时就是题目给的peek函数

    如果pop是空栈,但是push不是空,就把push依次出数据到pop,然后返回pop栈的栈顶元素

    此时再pop 2 3..都很好处理了

    还是在前面先写上我们栈的实现

    1. typedef struct {
    2. ST push;
    3. ST pop;
    4. } MyQueue;
    5. bool myQueueEmpty(MyQueue* obj) {
    6. return Empty(&obj->push) && Empty(&obj->pop);
    7. }
    8. MyQueue* myQueueCreate() {
    9. MyQueue* q=(MyQueue*)malloc(sizeof(MyQueue));
    10. InitST(&q->push);
    11. InitST(&q->pop);
    12. return q;
    13. }
    14. void myQueuePush(MyQueue* obj, int x) {
    15. assert(obj);
    16. PushST(&obj->push,x);
    17. }
    18. int myQueuePop(MyQueue* obj) {
    19. assert(obj);
    20. assert(!myQueueEmpty(obj));
    21. int peek=myQueuePeek(obj);
    22. PopST(&obj->pop);
    23. return peek;
    24. }
    25. int myQueuePeek(MyQueue* obj) {
    26. assert(obj);
    27. assert(!myQueueEmpty(obj));
    28. if(Empty(&obj->pop))
    29. {
    30. while(!Empty(&obj->push))
    31. {
    32. PushST(&obj->pop,StackTop(&obj->push));
    33. PopST(&obj->push);
    34. }
    35. }
    36. return StackTop(&obj->pop);
    37. }
    38. void myQueueFree(MyQueue* obj) {
    39. DestoryST(&obj->pop);
    40. DestoryST(&obj->push);
    41. free(obj);
    42. }

    学会了吗~~~

  • 相关阅读:
    Android 广播的注册和收发原理
    2022-08-26 第六小组 瞒春 学习笔记
    Python 哪种方式循环最快,或许颠覆你的认知
    golang学习笔记系列之一些标准库的学习(log,bytes,errors等)
    WPF 用户控件依赖注入赋值
    低代码工具大比拼:哪个最适合你?
    java毕业设计-超市会员积分管理系统-Mybatis+系统+数据库+调试部署
    懵了,面试官问我Redis怎么测,我哪知道!
    BEVM如何实现兼容OP Stack以WBTC为Gas的创新解决方案?
    Oracle数据库安装及配置
  • 原文地址:https://blog.csdn.net/weixin_71138261/article/details/127928791