马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
LeetCode 232: 用栈实现队列
标题形貌
利用栈实现队列的操纵。支持以下操纵:
- MyQueue():初始化队列。
- push(x):将元素 x 推入队列。
- pop():从队列中移除元素。
- peek():返回队列头部的元素。
- empty():查抄队列是否为空。
队列的先辈先出(FIFO)原则可以通过两个栈来模拟。栈 A 用于入队操纵,栈 B 用于出队操纵。
C 语言实现
- #include <stdio.h>
- #include <stdlib.h>
- // 定义栈结构体
- typedef struct {
- int* data;
- int top;
- int capacity;
- } Stack;
- // 初始化栈
- Stack* stackCreate(int capacity) {
- Stack* stack = (Stack*)malloc(sizeof(Stack));
- stack->data = (int*)malloc(sizeof(int) * capacity);
- stack->top = -1;
- stack->capacity = capacity;
- return stack;
- }
- // 检查栈是否为空
- int stackIsEmpty(Stack* stack) {
- return stack->top == -1;
- }
- // 入栈操作
- void stackPush(Stack* stack, int x) {
- stack->data[++stack->top] = x;
- }
- // 出栈操作
- int stackPop(Stack* stack) {
- return stack->data[stack->top--];
- }
- // 获取栈顶元素
- int stackTop(Stack* stack) {
- return stack->data[stack->top];
- }
- // 释放栈内存
- void stackFree(Stack* stack) {
- free(stack->data);
- free(stack);
- }
- // 定义队列结构体
- typedef struct {
- Stack* stackA;
- Stack* stackB;
- } MyQueue;
- // 初始化队列
- MyQueue* myQueueCreate() {
- MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
- queue->stackA = stackCreate(100); // 栈 A 的初始容量
- queue->stackB = stackCreate(100); // 栈 B 的初始容量
- return queue;
- }
- // 入队操作
- void myQueuePush(MyQueue* obj, int x) {
- stackPush(obj->stackA, x); // 将元素推入栈 A
- }
- // 出队操作
- int myQueuePop(MyQueue* obj) {
- if (stackIsEmpty(obj->stackB)) { // 如果栈 B 为空
- while (!stackIsEmpty(obj->stackA)) { // 将栈 A 中的元素全部移到栈 B
- stackPush(obj->stackB, stackPop(obj->stackA));
- }
- }
- return stackPop(obj->stackB); // 从栈 B 出栈
- }
- // 获取队列头部元素
- int myQueuePeek(MyQueue* obj) {
- if (stackIsEmpty(obj->stackB)) { // 如果栈 B 为空
- while (!stackIsEmpty(obj->stackA)) { // 将栈 A 中的元素全部移到栈 B
- stackPush(obj->stackB, stackPop(obj->stackA));
- }
- }
- return stackTop(obj->stackB); // 返回栈 B 顶部元素
- }
- // 检查队列是否为空
- int myQueueEmpty(MyQueue* obj) {
- return stackIsEmpty(obj->stackA) && stackIsEmpty(obj->stackB); // 栈 A 和栈 B 都为空时队列为空
- }
- // 释放队列内存
- void myQueueFree(MyQueue* obj) {
- stackFree(obj->stackA);
- stackFree(obj->stackB);
- free(obj);
- }
- // 测试主函数
- int main() {
- MyQueue* queue = myQueueCreate();
-
- myQueuePush(queue, 1);
- myQueuePush(queue, 2);
- printf("peek: %d\n", myQueuePeek(queue)); // 应输出 1
- printf("pop: %d\n", myQueuePop(queue)); // 应输出 1
- printf("empty: %d\n", myQueueEmpty(queue)); // 应输出 0
- myQueuePush(queue, 3);
- printf("peek: %d\n", myQueuePeek(queue)); // 应输出 2
- printf("pop: %d\n", myQueuePop(queue)); // 应输出 2
- printf("pop: %d\n", myQueuePop(queue)); // 应输出 3
- printf("empty: %d\n", myQueueEmpty(queue)); // 应输出 1
- myQueueFree(queue);
- return 0;
- }
复制代码 代码逐行表明
栈的实现
- typedef struct {
- int* data;
- int top;
- int capacity;
- } Stack;
复制代码 我们起首界说了一个 Stack 布局体,包罗了三个成员:
- data:存储栈元素的数组。
- top:栈顶元素的索引。
- capacity:栈的最大容量。
- Stack* stackCreate(int capacity) {
- Stack* stack = (Stack*)malloc(sizeof(Stack));
- stack->data = (int*)malloc(sizeof(int) * capacity);
- stack->top = -1;
- stack->capacity = capacity;
- return stack;
- }
复制代码 stackCreate 用来初始化一个栈,分配内存并设置初始值。- int stackIsEmpty(Stack* stack) {
- return stack->top == -1;
- }
复制代码 stackIsEmpty 用于查抄栈是否为空,栈空时返回 1。- void stackPush(Stack* stack, int x) {
- stack->data[++stack->top] = x;
- }
复制代码 stackPush 用于将元素推入栈中,top 先自增再将元素存入。- int stackPop(Stack* stack) {
- return stack->data[stack->top--];
- }
复制代码 stackPop 用于从栈中弹出元素,并返回弹出的元素。- int stackTop(Stack* stack) {
- return stack->data[stack->top];
- }
复制代码 stackTop 用于获取栈顶元素,但不删除它。
队列的实现
- typedef struct {
- Stack* stackA;
- Stack* stackB;
- } MyQueue;
复制代码 我们界说了一个 MyQueue 布局体,它包罗两个栈:
- stackA 用于存储入队元素。
- stackB 用于存储出队元素。
- MyQueue* myQueueCreate() {
- MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
- queue->stackA = stackCreate(100);
- queue->stackB = stackCreate(100);
- return queue;
- }
复制代码 myQueueCreate 用于创建一个队列并初始化此中的两个栈。- void myQueuePush(MyQueue* obj, int x) {
- stackPush(obj->stackA, x);
- }
复制代码 myQueuePush 将元素压入 stackA。- int myQueuePop(MyQueue* obj) {
- if (stackIsEmpty(obj->stackB)) {
- while (!stackIsEmpty(obj->stackA)) {
- stackPush(obj->stackB, stackPop(obj->stackA));
- }
- }
- return stackPop(obj->stackB);
- }
复制代码 myQueuePop 用于从队列中弹出元素。起首查抄 stackB 是否为空,假如为空,则将 stackA 中的全部元素转移到 stackB 中。然后从 stackB 弹出栈顶元素。- int myQueuePeek(MyQueue* obj) {
- if (stackIsEmpty(obj->stackB)) {
- while (!stackIsEmpty(obj->stackA)) {
- stackPush(obj->stackB, stackPop(obj->stackA));
- }
- }
- return stackTop(obj->stackB);
- }
复制代码 myQueuePeek 用于获取队列头部的元素,逻辑与 myQueuePop 类似,只不外不移除元素。- int myQueueEmpty(MyQueue* obj) {
- return stackIsEmpty(obj->stackA) && stackIsEmpty(obj->stackB);
- }
复制代码 myQueueEmpty 查抄队列是否为空,只有当 stackA 和 stackB 都为空时,队列才为空。- void myQueueFree(MyQueue* obj) {
- stackFree(obj->stackA);
- stackFree(obj->stackB);
- free(obj);
- }
复制代码 myQueueFree 用于开释队列及其内部栈的内存。
|