• 栈与队列经典题目——用栈实现队列


    上篇文章对栈和队列的一个经典题目——Leetcode.225-用队列实现栈进行讲解。本篇文章将对另一个题目Leetcode.232-用栈实现队列进行讲解

    1. Leetcode.232——用栈实现队列:

    题目如下:


    1.1 大体思路分析:

    题目要求需要实现下列函数所表示的功能,即:myQueueCreate(创建队列),myQueuePush(用栈实现队列尾插),myQueuePeek(返回队列的开头元素),myQueuePop(移除、返回队列开头元素),myQueueEmpty(探空),myQueueFree(释放问题解决过程中开辟的空间)。

    对于上述给出需要实现的功能中,较为重要的是myQueuePeek(返回队列的开头元素),myQueuePop(移除、返回队列开头元素),在本部分,将介绍这两种功能的实现思路。

    对于栈,可以看作只能在尾部进行插入删除的线性表,对于队列,是尾部进行插入,头部进行删除的线性表。下面给出一个包含若干元素的栈,即:

    题目要求用两个栈来实现队列,则,将上述栈中的元素插入到另一个栈后,及:

    此时,栈的尾部存储的元素为1,按照栈的规则,尾部插入元素,尾部删除元素,则可以达到上述给出的函数(移除、返回队列开头元素)所对应的移除开头元素的功能。对于返回队列开头元素,只需要在移除元素之前,单独创建一个变量用于存储元素1,移除元素,最后返回用于存储元素1的变量即可。

    在利用队列实现栈的题目中,需要一个结构体指针指向一个保持为空的队列,令一个结构体指针指向的队列 用于插入元素。通过上面给出思路可知,本题需要的两个栈,一个用来接受插入的元素,将这个栈定义为Pushst,另一个栈需要接受Pushst的栈顶元素,并在之后通过出栈顶元素来实现队列关于头元素的各项功能。

    1.2 功能实现:

    1.2.1 栈的创建及初始化:

    初始化的过程与上篇文章的中初始化原理相同,不过多赘述,只给出代码:
     

    1. typedef struct {
    2. ST pushst;
    3. ST Popst;
    4. } MyQueue;
    5. MyQueue* myQueueCreate() {
    6. MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    7. STInit(&obj->pushst);
    8. STInit(&obj->Popst);
    9. return obj;
    10. }

    1.2.2 通过栈顶插入元素 myQueuePush:

    虽然栈与队列在删除元素时由一定不同,但是在插入元素时,队列是在队尾插入,栈是在栈顶,即同样是队尾插入,所以,直接调用函数STPush,向队尾位置插入元素即可,代码如下:
     

    1. void myQueuePush(MyQueue* obj, int x) {
    2. STPush(&obj->pushst,x);
    3. }

    1.2.3 返回队列的开头元素myQueuePeek:

    上面给出了实现本功能的大体思路。但是需要区分下面两种情况,即:Popst栈中为空、Popst栈中已经存在元素。对于前一种情况,需要将Pushst中的所有元素都插入到Popst,最后取栈顶元素返回即可。对于后一种情况,直接取栈顶元素返回即可。

    对应代码如下:
     

    1. int myQueuePeek(MyQueue* obj) {
    2. if( STEmpty(&obj->Popst))
    3. {
    4. while(!STEmpty(&obj->pushst))
    5. {
    6. STPush(&obj->Popst,STTop(&obj->pushst));
    7. STPop(&obj->pushst);
    8. }
    9. }
    10. return STTop(&obj->Popst);
    11. }

    1.2.3 从队头删除并返回队头元素myQueuePop

    上个功能中,已经实现了返回栈顶元素,所以在实现本功能时,只需要创建一个变量front用于存储myQueuePeek的返回值,再移除栈顶元素,最后返回front即可。对应代码如下:

    1. int myQueuePop(MyQueue* obj) {
    2. int front = myQueuePeek(obj);
    3. STPop(&obj->Popst);
    4. return front;
    5. }

    1.2.4 探空myQueueEmpty

    原理较为简单,只给出代码,不做多余解释:

    1. bool myQueueEmpty(MyQueue* obj) {
    2. return STEmpty(&obj->Popst) && STEmpty(&obj->pushst);
    3. }

    1.2.5 释放解决问题所开辟的空间myQueueFree

    同样,只给出代码,不做多余解释:

    1. void myQueueFree(MyQueue* obj) {
    2. STDestory(&obj->pushst);
    3. STDestory(&obj->Popst);
    4. free(obj);
    5. }

    2. 结果及代码总览:

    2.1 运行结果:



    2.2 代码总览:

    1. typedef int STDataType;
    2. typedef struct Stack
    3. {
    4. STDataType* a;
    5. int top;
    6. int capacity;
    7. }ST;
    8. //栈的初始化:
    9. void STInit( ST* ps )
    10. {
    11. assert(ps);
    12. ps->a = NULL;
    13. ps->top = ps->capacity = 0;
    14. }
    15. //栈的销毁:
    16. void STDestory(ST* ps)
    17. {
    18. assert(ps);
    19. free(ps->a);
    20. ps->a = NULL;
    21. ps->top = ps->capacity = 0;
    22. }
    23. void STPush(ST* ps, STDataType x)
    24. {
    25. assert(ps);
    26. if (ps->top == ps->capacity)
    27. {
    28. int newcapacity = ps->capacity == 0 ? ps->capacity = 4: ps->capacity * 2;
    29. STDataType* newnode = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);
    30. if (newnode == NULL)
    31. {
    32. perror("realloc");
    33. }
    34. ps->a = newnode;
    35. ps->capacity = newcapacity;
    36. }
    37. ps->a[ps->top] = x;
    38. ps->top++;
    39. }
    40. void STPop(ST* ps)
    41. {
    42. assert(ps);
    43. assert(ps->top > 0);
    44. ps->top--;
    45. }
    46. int size(ST* ps)
    47. {
    48. assert(ps);
    49. return ps->top;
    50. }
    51. bool STEmpty(ST* ps)
    52. {
    53. assert(ps);
    54. return ps->top == 0;
    55. }
    56. STDataType STTop(ST* ps)
    57. {
    58. assert(ps);
    59. assert(ps->top > 0);
    60. return ps->a[ps->top-1];
    61. }
    62. //栈的初始化:
    63. void STInit(ST* ps);
    64. //栈的销毁
    65. void STDestory(ST* ps);
    66. //通过栈顶向栈中插入元素
    67. void STPush(ST* ps, STDataType x);
    68. //删除栈中的元素:
    69. void STPop(ST* ps);
    70. //记录size
    71. int size(ST* ps);
    72. //找空
    73. bool STEmpty(ST* ps);
    74. //获取栈顶元素
    75. STDataType STTop(ST* ps);
    76. typedef struct {
    77. ST pushst;
    78. ST Popst;
    79. } MyQueue;
    80. MyQueue* myQueueCreate() {
    81. MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    82. STInit(&obj->pushst);
    83. STInit(&obj->Popst);
    84. return obj;
    85. }
    86. void myQueuePush(MyQueue* obj, int x) {
    87. STPush(&obj->pushst,x);
    88. }
    89. int myQueuePeek(MyQueue* obj) {
    90. if( STEmpty(&obj->Popst))
    91. {
    92. while(!STEmpty(&obj->pushst))
    93. {
    94. STPush(&obj->Popst,STTop(&obj->pushst));
    95. STPop(&obj->pushst);
    96. }
    97. }
    98. return STTop(&obj->Popst);
    99. }
    100. int myQueuePop(MyQueue* obj) {
    101. int front = myQueuePeek(obj);
    102. STPop(&obj->Popst);
    103. return front;
    104. }
    105. bool myQueueEmpty(MyQueue* obj) {
    106. return STEmpty(&obj->Popst) && STEmpty(&obj->pushst);
    107. }
    108. void myQueueFree(MyQueue* obj) {
    109. STDestory(&obj->pushst);
    110. STDestory(&obj->Popst);
    111. free(obj);
    112. }


     



     

  • 相关阅读:
    pip的基本命令和使用
    python函数的定义及使用
    【设计模式】单例模式
    雷尼绍探头编程 9810
    ubuntu编译安装并测试opencv
    【ROS入门】雷达、摄像头及kinect信息仿真以及显示
    xhadmin多应用Saas框架如何安装情侣飞行棋?
    Python之类对象
    R语言使用data.table包的fread函数读取(加载)csv数据为data.table格式、使用summary函数查看数据的汇总统计信息
    DeepMind 利用无监督学习开发 AlphaMissense,预测 7100 万种基因突变
  • 原文地址:https://blog.csdn.net/2301_76836325/article/details/132924425