LeetCode 232: 用栈实现队列

[复制链接]
发表于 2025-10-31 13:16:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
LeetCode 232: 用栈实现队列

标题形貌

利用栈实现队列的操纵。支持以下操纵:

  • MyQueue():初始化队列。
  • push(x):将元素 x 推入队列。
  • pop():从队列中移除元素。
  • peek():返回队列头部的元素。
  • empty():查抄队列是否为空。
队列的先辈先出(FIFO)原则可以通过两个栈来模拟。栈 A 用于入队操纵,栈 B 用于出队操纵。
C 语言实现
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义栈结构体
  4. typedef struct {
  5.     int* data;
  6.     int top;
  7.     int capacity;
  8. } Stack;
  9. // 初始化栈
  10. Stack* stackCreate(int capacity) {
  11.     Stack* stack = (Stack*)malloc(sizeof(Stack));
  12.     stack->data = (int*)malloc(sizeof(int) * capacity);
  13.     stack->top = -1;
  14.     stack->capacity = capacity;
  15.     return stack;
  16. }
  17. // 检查栈是否为空
  18. int stackIsEmpty(Stack* stack) {
  19.     return stack->top == -1;
  20. }
  21. // 入栈操作
  22. void stackPush(Stack* stack, int x) {
  23.     stack->data[++stack->top] = x;
  24. }
  25. // 出栈操作
  26. int stackPop(Stack* stack) {
  27.     return stack->data[stack->top--];
  28. }
  29. // 获取栈顶元素
  30. int stackTop(Stack* stack) {
  31.     return stack->data[stack->top];
  32. }
  33. // 释放栈内存
  34. void stackFree(Stack* stack) {
  35.     free(stack->data);
  36.     free(stack);
  37. }
  38. // 定义队列结构体
  39. typedef struct {
  40.     Stack* stackA;
  41.     Stack* stackB;
  42. } MyQueue;
  43. // 初始化队列
  44. MyQueue* myQueueCreate() {
  45.     MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
  46.     queue->stackA = stackCreate(100); // 栈 A 的初始容量
  47.     queue->stackB = stackCreate(100); // 栈 B 的初始容量
  48.     return queue;
  49. }
  50. // 入队操作
  51. void myQueuePush(MyQueue* obj, int x) {
  52.     stackPush(obj->stackA, x);  // 将元素推入栈 A
  53. }
  54. // 出队操作
  55. int myQueuePop(MyQueue* obj) {
  56.     if (stackIsEmpty(obj->stackB)) {  // 如果栈 B 为空
  57.         while (!stackIsEmpty(obj->stackA)) {  // 将栈 A 中的元素全部移到栈 B
  58.             stackPush(obj->stackB, stackPop(obj->stackA));
  59.         }
  60.     }
  61.     return stackPop(obj->stackB);  // 从栈 B 出栈
  62. }
  63. // 获取队列头部元素
  64. int myQueuePeek(MyQueue* obj) {
  65.     if (stackIsEmpty(obj->stackB)) {  // 如果栈 B 为空
  66.         while (!stackIsEmpty(obj->stackA)) {  // 将栈 A 中的元素全部移到栈 B
  67.             stackPush(obj->stackB, stackPop(obj->stackA));
  68.         }
  69.     }
  70.     return stackTop(obj->stackB);  // 返回栈 B 顶部元素
  71. }
  72. // 检查队列是否为空
  73. int myQueueEmpty(MyQueue* obj) {
  74.     return stackIsEmpty(obj->stackA) && stackIsEmpty(obj->stackB);  // 栈 A 和栈 B 都为空时队列为空
  75. }
  76. // 释放队列内存
  77. void myQueueFree(MyQueue* obj) {
  78.     stackFree(obj->stackA);
  79.     stackFree(obj->stackB);
  80.     free(obj);
  81. }
  82. // 测试主函数
  83. int main() {
  84.     MyQueue* queue = myQueueCreate();
  85.    
  86.     myQueuePush(queue, 1);
  87.     myQueuePush(queue, 2);
  88.     printf("peek: %d\n", myQueuePeek(queue));  // 应输出 1
  89.     printf("pop: %d\n", myQueuePop(queue));   // 应输出 1
  90.     printf("empty: %d\n", myQueueEmpty(queue));  // 应输出 0
  91.     myQueuePush(queue, 3);
  92.     printf("peek: %d\n", myQueuePeek(queue));  // 应输出 2
  93.     printf("pop: %d\n", myQueuePop(queue));   // 应输出 2
  94.     printf("pop: %d\n", myQueuePop(queue));   // 应输出 3
  95.     printf("empty: %d\n", myQueueEmpty(queue));  // 应输出 1
  96.     myQueueFree(queue);
  97.     return 0;
  98. }
复制代码
代码逐行表明

栈的实现
  1. typedef struct {
  2.     int* data;
  3.     int top;
  4.     int capacity;
  5. } Stack;
复制代码
我们起首界说了一个 Stack 布局体,包罗了三个成员:

  • data:存储栈元素的数组。
  • top:栈顶元素的索引。
  • capacity:栈的最大容量。
  1. Stack* stackCreate(int capacity) {
  2.     Stack* stack = (Stack*)malloc(sizeof(Stack));
  3.     stack->data = (int*)malloc(sizeof(int) * capacity);
  4.     stack->top = -1;
  5.     stack->capacity = capacity;
  6.     return stack;
  7. }
复制代码
stackCreate 用来初始化一个栈,分配内存并设置初始值。
  1. int stackIsEmpty(Stack* stack) {
  2.     return stack->top == -1;
  3. }
复制代码
stackIsEmpty 用于查抄栈是否为空,栈空时返回 1。
  1. void stackPush(Stack* stack, int x) {
  2.     stack->data[++stack->top] = x;
  3. }
复制代码
stackPush 用于将元素推入栈中,top 先自增再将元素存入。
  1. int stackPop(Stack* stack) {
  2.     return stack->data[stack->top--];
  3. }
复制代码
stackPop 用于从栈中弹出元素,并返回弹出的元素。
  1. int stackTop(Stack* stack) {
  2.     return stack->data[stack->top];
  3. }
复制代码
stackTop 用于获取栈顶元素,但不删除它。
队列的实现
  1. typedef struct {
  2.     Stack* stackA;
  3.     Stack* stackB;
  4. } MyQueue;
复制代码
我们界说了一个 MyQueue 布局体,它包罗两个栈:

  • stackA 用于存储入队元素。
  • stackB 用于存储出队元素。
  1. MyQueue* myQueueCreate() {
  2.     MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
  3.     queue->stackA = stackCreate(100);
  4.     queue->stackB = stackCreate(100);
  5.     return queue;
  6. }
复制代码
myQueueCreate 用于创建一个队列并初始化此中的两个栈。
  1. void myQueuePush(MyQueue* obj, int x) {
  2.     stackPush(obj->stackA, x);  
  3. }
复制代码
myQueuePush 将元素压入 stackA。
  1. int myQueuePop(MyQueue* obj) {
  2.     if (stackIsEmpty(obj->stackB)) {
  3.         while (!stackIsEmpty(obj->stackA)) {
  4.             stackPush(obj->stackB, stackPop(obj->stackA));
  5.         }
  6.     }
  7.     return stackPop(obj->stackB);
  8. }
复制代码
myQueuePop 用于从队列中弹出元素。起首查抄 stackB 是否为空,假如为空,则将 stackA 中的全部元素转移到 stackB 中。然后从 stackB 弹出栈顶元素。
  1. int myQueuePeek(MyQueue* obj) {
  2.     if (stackIsEmpty(obj->stackB)) {
  3.         while (!stackIsEmpty(obj->stackA)) {
  4.             stackPush(obj->stackB, stackPop(obj->stackA));
  5.         }
  6.     }
  7.     return stackTop(obj->stackB);
  8. }
复制代码
myQueuePeek 用于获取队列头部的元素,逻辑与 myQueuePop 类似,只不外不移除元素。
  1. int myQueueEmpty(MyQueue* obj) {
  2.     return stackIsEmpty(obj->stackA) && stackIsEmpty(obj->stackB);
  3. }
复制代码
myQueueEmpty 查抄队列是否为空,只有当 stackA 和 stackB 都为空时,队列才为空。
  1. void myQueueFree(MyQueue* obj) {
  2.     stackFree(obj->stackA);
  3.     stackFree(obj->stackB);
  4.     free(obj);
  5. }
复制代码
myQueueFree 用于开释队列及其内部栈的内存。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表