• 225. 用队列实现栈-C语言


    题目来源:力扣

    题目描述:

    请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

    实现 MyStack 类:

    • void push(int x) 将元素 x 压入栈顶。
    • int pop() 移除并返回栈顶元素。
    • int top() 返回栈顶元素。
    • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
    • 注意:
    • 你只能使用队列的基本操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
    • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

    示例:

    输入:
    ["MyStack", "push", "push", "top", "pop", "empty"]
    [[], [1], [2], [], [], []]
    输出:
    [null, null, null, 2, 2, false]
    
    解释:
    MyStack myStack = new MyStack();
    myStack.push(1);
    myStack.push(2);
    myStack.top(); // 返回 2
    myStack.pop(); // 返回 2
    myStack.empty(); // 返回 False

    提示:

    • 1 <= x <= 9
    • 最多调用100 次 pushpoptop 和 empty
    • 每次调用 pop 和 top 都保证栈不为空

    思路:

    栈的特点是后进先出,队列的特点是先进先出,根据这些的特点,并且让我们使用两个队列来完成栈,我们可以利用队列的特点互相倒数据来完成栈,比如一个队列里有元素1,2,3,4,5,另一个队列为空,我们此时要出栈得到5,我们可以让有数据队列的前四个元素都入到另一个队列里,然后把剩下的那一个元素出栈即可,出栈前我们可以先定义空队列和非空两个指针,用来指向对应的队列,方便后续操作,入栈的话要根据哪个队列有元素就入哪个队列,销毁要先释放两个队列的空间,然后再释放整个栈的空间,初始化要先给栈申请空间,否则就是局部变量,然后要给两个队列初始化

    代码实现:

    1. typedef int QDataType;
    2. typedef struct QueueNode
    3. {
    4. struct QueueNode* next;
    5. QDataType data;
    6. }QNode;
    7. typedef struct Queue
    8. {
    9. QNode* head;
    10. QNode* tail;
    11. }Queue;
    12. void QueueInit(Queue* pq);//初始化
    13. void QueueDestory(Queue* pq);//销毁
    14. void QueuePush(Queue* pq, QDataType x);//入队列
    15. void QueuePop(Queue* pq);//出队列
    16. QDataType QueueFront(Queue* pq);//取队头元素
    17. QDataType QueueBack(Queue* pq);//取队尾元素
    18. int QueueSize(Queue* pq);//取数据个数
    19. bool QueueEmpty(Queue* pq);//判断是否为空
    20. void QueueInit(Queue* pq)//初始化
    21. {
    22. assert(pq);
    23. pq->head = pq->tail = NULL;
    24. }
    25. void QueueDestory(Queue* pq)//销毁
    26. {
    27. assert(pq);
    28. QNode* cur = pq->head;
    29. while (cur) {
    30. QNode* next = cur->next;
    31. free(cur);
    32. cur = next;
    33. }
    34. pq->head = pq->tail = NULL;
    35. }
    36. void QueuePush(Queue* pq, QDataType x)//入队列
    37. {
    38. assert(pq);
    39. QNode* newnode = (QNode*)malloc(sizeof(QNode));
    40. if (newnode == NULL) {
    41. printf("malloc fail\n");
    42. exit(-1);
    43. }
    44. newnode->data = x;
    45. newnode->next = NULL;
    46. if (pq->tail == NULL) {
    47. pq->head = pq->tail = newnode;
    48. }
    49. else {
    50. pq->tail->next = newnode;
    51. pq->tail = newnode;
    52. }
    53. }
    54. void QueuePop(Queue* pq)//出队列
    55. {
    56. assert(pq);
    57. assert(pq->head);
    58. if (pq->head->next == NULL) {
    59. free(pq->head);
    60. pq->head = pq->tail = NULL;
    61. }
    62. else {
    63. Queue* next = pq->head->next;
    64. free(pq->head);
    65. pq->head = next;
    66. }
    67. }
    68. QDataType QueueFront(Queue* pq)//取队头元素
    69. {
    70. assert(pq);
    71. assert(pq->head);
    72. return pq->head->data;
    73. }
    74. QDataType QueueBack(Queue* pq)//取队尾元素
    75. {
    76. assert(pq);
    77. assert(pq->head);
    78. return pq->tail->data;
    79. }
    80. int QueueSize(Queue* pq)//计算数据个数
    81. {
    82. assert(pq);
    83. int size = 0;
    84. QNode* cur = pq->head;
    85. while (cur) {
    86. cur = cur->next;
    87. size++;
    88. }
    89. return size;
    90. }
    91. bool QueueEmpty(Queue* pq)//判断是否为空
    92. {
    93. assert(pq);
    94. return pq->head == NULL;
    95. }
    96. typedef struct {
    97. Queue q1;
    98. Queue q2;
    99. } MyStack;
    100. MyStack* myStackCreate() {
    101. MyStack* ps=(MyStack*)malloc(sizeof(MyStack));
    102. if(ps==NULL){
    103. printf("malloc fail\n");
    104. exit(-1);
    105. }
    106. QueueInit(&ps->q1);
    107. QueueInit(&ps->q2);
    108. return ps;
    109. }
    110. void myStackPush(MyStack* obj, int x) {
    111. if(!QueueEmpty(&obj->q1)){
    112. QueuePush(&obj->q1,x);
    113. }else{
    114. QueuePush(&obj->q2,x);
    115. }
    116. }
    117. int myStackPop(MyStack* obj) {
    118. Queue* emptyQ = &obj->q1;
    119. Queue* nonemptyQ = &obj->q2;
    120. if(!QueueEmpty(&obj->q1)){
    121. nonemptyQ = &obj->q1;
    122. emptyQ = &obj->q2;
    123. }
    124. while(QueueSize(nonemptyQ)>1){
    125. QueuePush(emptyQ,QueueFront(nonemptyQ));
    126. QueuePop(nonemptyQ);
    127. }
    128. int top=QueueFront(nonemptyQ);
    129. QueuePop(nonemptyQ);
    130. return top;
    131. }
    132. int myStackTop(MyStack* obj) {
    133. if(!QueueEmpty(&obj->q1)){
    134. return QueueBack(&obj->q1);
    135. }else{
    136. return QueueBack(&obj->q2);
    137. }
    138. }
    139. bool myStackEmpty(MyStack* obj) {
    140. return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
    141. }
    142. void myStackFree(MyStack* obj) {
    143. QueueDestory(&obj->q1);
    144. QueueDestory(&obj->q2);
    145. free(obj);
    146. }
    147. /**
    148. * Your MyStack struct will be instantiated and called as such:
    149. * MyStack* obj = myStackCreate();
    150. * myStackPush(obj, x);
    151. * int param_2 = myStackPop(obj);
    152. * int param_3 = myStackTop(obj);
    153. * bool param_4 = myStackEmpty(obj);
    154. * myStackFree(obj);
    155. */

    运行结果:

     

  • 相关阅读:
    数据结构笔记01
    程序调试技巧
    ESP32网络开发实例-异步Web服务器
    大模型日报 2024-07-12
    应用程序无法启动,因为应用程序的并行配置不正确。有关详细信息,请参阅应用程序事件日志,或使用命令行 sxstrace.exe 工具。
    我的256天创作纪念日
    小白 | 零基础 | 转行 | 六个月 Java 学习路线
    单链表经典例题
    C#/.NET/.NET Core优秀项目和框架精选(坑已挖,欢迎大家踊跃提交PR或者Issues中留言)
    2023年中国稻谷加工机械分类、市场规模及发展前景分析[图]
  • 原文地址:https://blog.csdn.net/KLZUQ/article/details/128064942