• 【LeetCode】用队列实现栈和用栈实现队列(C语言)


    目录

    1.用队列实现栈

     增删

     求栈顶元素

     判断栈为空

    2.用栈实现队列 

     增删

    返回队列开头的数据 

    判断队列为空

    尾言

    源码

    队列实现栈

    栈实现队列


    刚讲完栈和队列,LeetCode上有两题栈与队列的互相实现,简单地讲讲思路和实现吧。

    1.用队列实现栈

    原题地址:225.用队列实现栈

     题目要求我们用两个队列来实现一个栈,我们知道队列的性质是先进先出,而栈是后进先出,假设随便给我们要的这个栈之中添加几个数,便能画出这样的图

     增删

    那这样接下来若要出栈,输出的便是 ,但是队列出队的话只能输出 。所以我们就要用到另一个队列,把队列1最后一个数前面的数据导入到队列2之后再输出队列1的唯一数。这样就完成了出栈的模拟。

    之后把队列1第一个数据删除,一定保证一个队列为空 ,即第二次出栈还是要把非空的队列的数据导入空队列里去。

     若是要入栈操作的话就是直接再非空队列队尾插入数据就可以了,最后面的值不会被导入到另一队列里。所以下次出栈就会将其输出。

     求栈顶元素

    找栈顶元素其实与出栈的唯一不同就是,出栈要删除栈顶元素,而求栈顶元素不一样,其要求要有返回值。偷懒的话可以先写求栈顶元素,之后出栈只要复用函数就可以完成了。

     判断栈为空

     前面讲过,必定有一个队列为空,因此不能只检查一个队列而是两个队列都要检查,即两个队列都为空则证明栈为空。

    2.用栈实现队列 

    原题地址:232.用栈实现队列

    其实只要熟悉了队列和栈的基本性质,其实这两题也并不会很难,思路正确了剩下的就只需要注意编写程序时的小细节就可以了。 

     增删

    仔细分析题目,要求用两个栈实现一个队列,既然题目都这样要求了只用一个栈明显是不可能的,上一题的经验告诉我,要把数据导入到另一个栈里。

     把数据导到另一个栈后我们惊奇的发现,数据恰好就成了我们想要的样子。这段数据就可以直接输出了。

     这下我们就可以让一个栈专门承载输入数据,另一个栈专门输出数据,输出栈为空时再从输入栈把数据导入到输出栈里面。

    返回队列开头的数据 

    也是跟删除是一个道理,不过只是返回值并不删除数据。即输出栈没有值就导入输入栈的值进去就可以了。

    判断队列为空

     两个栈如果都为空,队列就为空,只有其中一个栈为空是不算的。

     

    尾言

     好了,这样今天我们两道题的思路与实现到这里就讲完了,说实在的用C语言写确实是麻烦了一点,但是之前写过栈和队列的话直接把代码复制过去,之后用自己之前写的函数写就可以了。有问题的话一定私信或者评论区指出,一定第一时间回复!!!

    源码

    队列实现栈

    1. typedef int Qdatatype;
    2. typedef struct Qnode
    3. {
    4. Qdatatype data;
    5. struct Queue* next;
    6. }Qnode;
    7. typedef struct Queue
    8. {
    9. Qnode* head;
    10. Qnode* tail;
    11. int size;
    12. }Queue;
    13. void Queueinit(Queue* p)
    14. {
    15. p->head = NULL;
    16. p->tail = NULL;
    17. p->size = 0;
    18. }
    19. bool QueueEmpty(Queue* p)
    20. {
    21. assert(p);
    22. return p->head == NULL || p->tail == NULL;
    23. }
    24. void Queuepush(Queue* p, Qdatatype x)
    25. {
    26. assert(p);
    27. Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
    28. if (newnode == NULL)
    29. {
    30. perror(malloc);
    31. exit(-1);
    32. }
    33. newnode->data = x;
    34. newnode->next = NULL;
    35. if (p->head == NULL)
    36. {
    37. p->head = p->tail = newnode;
    38. p->size++;
    39. }
    40. else
    41. {
    42. p->tail->next = newnode;
    43. p->tail = newnode;
    44. p->size++;
    45. }
    46. }
    47. void Queuepop(Queue* p)
    48. {
    49. assert(p);
    50. assert(!QueueEmpty(p));
    51. Qnode* next = p->head->next;
    52. free(p->head);
    53. p->head = next;
    54. p->size--;
    55. }
    56. Qdatatype Queuefront(Queue* p)
    57. {
    58. assert(p);
    59. return p->head->data;
    60. }
    61. void QueueDestroy(Queue* p)
    62. {
    63. assert(p);
    64. Qnode* cur = p->head;
    65. while (cur)
    66. {
    67. Qnode* next = cur->next;
    68. free(cur);
    69. cur = next;
    70. }
    71. p->head = p->tail = NULL;
    72. p->size = 0;
    73. }
    74. Qdatatype Queueback(Queue* p)
    75. {
    76. assert(p);
    77. assert(!QueueEmpty(p));
    78. return p->tail->data;
    79. }
    80. int Queuesize(Queue* p)
    81. {
    82. assert(p);
    83. return p->size;
    84. }
    85. typedef struct {
    86. Queue q1;
    87. Queue q2;
    88. } MyStack;
    89. MyStack* myStackCreate() {
    90. MyStack* stack = (MyStack*)malloc(sizeof(MyStack)); //开辟栈的空间,动态开辟才不是局部变量
    91. Queueinit(&stack->q1); //两个队列的初始化
    92. Queueinit(&stack->q2);
    93. return stack;
    94. }
    95. void myStackPush(MyStack* obj, int x) {
    96. assert(obj);
    97. if (!QueueEmpty(&obj->q1)) //在非空队列里插入数据,两个都为空则默认插入在第一个里面
    98. {
    99. return Queuepush(&obj->q1, x);
    100. }
    101. else
    102. {
    103. return Queuepush(&obj->q2, x);
    104. }
    105. }
    106. int myStackPop(MyStack* obj) {
    107. assert(obj);
    108. Queue* emptyqueue = &obj->q1; //一定有一个空队列
    109. Queue* queue = &obj->q2; //一个是有数据的队列
    110. if (QueueEmpty(&obj->q2)) //判断为空的队列
    111. {
    112. emptyqueue = &obj->q2;
    113. queue = &obj->q1;
    114. }
    115. while (Queuesize(queue) > 1)
    116. {
    117. Queuepush(emptyqueue, Queuefront(queue)); //导入后删除原队列里的数据
    118. Queuepop(queue);
    119. }
    120. int ret = Queuefront(queue);
    121. Queuepop(queue);
    122. return ret;
    123. }
    124. int myStackTop(MyStack* obj) {
    125. assert(obj);
    126. if (!QueueEmpty(&obj->q1))
    127. {
    128. return Queueback(&obj->q1);
    129. }
    130. else
    131. {
    132. return Queueback(&obj->q2);
    133. }
    134. }
    135. bool myStackEmpty(MyStack* obj) {
    136. assert(obj);
    137. return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
    138. }

    栈实现队列

     

    1. typedef int STdatatype;
    2. typedef struct Stack
    3. {
    4. STdatatype* data;
    5. int top;
    6. int capacity;
    7. }Stack;
    8. void checkcapacity(Stack* p)
    9. {
    10. STdatatype* newp;
    11. if (p->top == p->capacity)
    12. {
    13. newp = (STdatatype*)realloc(p->data, sizeof(Stack) * p->capacity * 2);
    14. if (newp == NULL)
    15. {
    16. perror(realloc);
    17. exit(-1);
    18. }
    19. p->data = newp;
    20. p->capacity *= 2;
    21. }
    22. if (p == NULL)
    23. {
    24. perror(realloc);
    25. exit(-1);
    26. }
    27. }
    28. void StackInit(Stack* p)
    29. {
    30. STdatatype* np = (STdatatype*)malloc(sizeof(STdatatype) * 4);
    31. if (np)
    32. {
    33. p->data = np;
    34. }
    35. p->top = 0;
    36. p->capacity = 4;
    37. }
    38. void StackPush(Stack* p, STdatatype x)
    39. {
    40. assert(p);
    41. checkcapacity(p);
    42. (p->data)[p->top] = x;
    43. p->top++;
    44. }
    45. void Stackprint(Stack* p)
    46. {
    47. int i = p->top - 1;
    48. while (i >= 0)
    49. {
    50. printf("%d ", (p->data)[i--]);
    51. }
    52. printf("\n");
    53. }
    54. void StackPop(Stack* p)
    55. {
    56. assert(p);
    57. assert(p->top);
    58. p->top--;
    59. }
    60. STdatatype StackTop(Stack* p)
    61. {
    62. assert(p);
    63. int top = p->top - 1;
    64. return (p->data)[top];
    65. }
    66. int StackEmpty(Stack* p)
    67. {
    68. assert(p);
    69. if (p->top != 0)
    70. {
    71. return 0;
    72. }
    73. return 1;
    74. }
    75. void StackDestroy(Stack* p)
    76. {
    77. assert(p);
    78. assert(p->data);
    79. free(p->data);
    80. p->data = NULL;
    81. p->top = 0;
    82. p->capacity = 0;
    83. }
    84. typedef struct //两个队列一个输出一个输入,输出栈里没数据了之后就从输入里面倒数据过去
    85. {
    86. Stack S; //输入
    87. Stack nullS; //输出
    88. } MyQueue;
    89. bool myQueueEmpty(MyQueue* obj);
    90. int myQueuePeek(MyQueue* obj);
    91. MyQueue* myQueueCreate() //创建队列
    92. {
    93. MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue)); //开辟队列空间
    94. StackInit(&queue->S); //对两个栈初始化
    95. StackInit(&queue->nullS);
    96. return queue; //返回开辟的队列
    97. }
    98. void myQueuePush(MyQueue* obj, int x) {
    99. assert(obj);
    100. StackPush(&obj->S, x); //直接在插入的队列里插入数据
    101. }
    102. int myQueuePop(MyQueue* obj) {
    103. assert(obj);
    104. assert(!myQueueEmpty(obj)); //判断队列不为空
    105. int ret = myQueuePeek(obj); //取最上面的值返回
    106. StackPop(&obj->nullS); //pop在peek的基础上增加数据的删除
    107. return ret;
    108. }
    109. int myQueuePeek(MyQueue* obj) { //拿最前面的数据
    110. assert(obj);
    111. assert(!myQueueEmpty(obj)); //队列不为空
    112. if (StackEmpty(&obj->nullS)) //输出栈为空则倒入数据
    113. {
    114. while (!StackEmpty(&obj->S)) //直到输入栈为空,必定一个栈为空
    115. {
    116. StackPush(&obj->nullS, StackTop(&obj->S)); //取输入栈最上面导入到输出栈的最下面
    117. StackPop(&obj->S); //清除输入栈的数据
    118. }
    119. }
    120. return StackTop(&obj->nullS); //返回最上面的值
    121. }
    122. bool myQueueEmpty(MyQueue* obj) {
    123. assert(obj);
    124. return StackEmpty(&obj->nullS) && StackEmpty(&obj->S); //两个栈都为空则队列为空
    125. }
    126. void myQueueFree(MyQueue* obj) {
    127. assert(obj);
    128. StackDestroy(&obj->nullS); //销毁两个栈
    129. StackDestroy(&obj->S);
    130. free(obj); //销毁队列
    131. }

  • 相关阅读:
    go mod tidy 报错:x509: certificate signed by unknown authority 最佳实践
    MongoDB副本集调整节点
    摩尔斯密码
    Java基础抽象类详解
    稀土/铜催化剂电催化CO2制C2+或CH4
    宝宝每天需要补充多少钙?宝宝睡觉出汗枕秃是缺钙吗?
    基于ssm的搬家管理系统
    物通博联持续参与京东方(BOE)工厂数字化项目
    22年6月工作笔记整理(前端)
    VirtualBox Win7 虚拟机 共享文件夹设置
  • 原文地址:https://blog.csdn.net/Lin_Alpaca/article/details/127929385