前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【C语言】用栈实现队列篇

【C语言】用栈实现队列篇

作者头像
用户11456817
发布2025-02-15 13:17:16
发布2025-02-15 13:17:16
4200
代码可运行
举报
文章被收录于专栏:学习
运行总次数:0
代码可运行

一、数据结构基础回顾

1.1 栈(Stack)

特性:后进先出(LIFO)

  • 核心操作:
    • push: 元素入栈
    • pop: 栈顶元素出栈
    • peek: 查看栈顶元素
1.2 队列(Queue)

特性:先进先出(FIFO)

  • 核心操作:
    • enqueue: 元素入队
    • dequeue: 队首元素出队
    • front: 查看队首元素

二、问题分析与解决方案

2.1 核心矛盾

栈的LIFO特性与队列的FIFO需求存在根本性冲突,单个栈无法直接实现队列。

2.2 双栈方案

使用两个栈协同工作:

  • 输入栈(input_stack):专门处理入队操作
  • 输出栈(output_stack):专门处理出队操作
2.3 算法流程
代码语言:javascript
代码运行次数:0
复制
// 入队操作
void enQueue(Queue* queue, int value) {
    push(&queue->input_stack, value);
}

// 出队操作
int deQueue(Queue* queue) {
    if (isStackEmpty(&queue->output_stack)) {
        // 当输出栈为空时,转移全部元素
        while (!isStackEmpty(&queue->input_stack)) {
            push(&queue->output_stack, pop(&queue->input_stack));
        }
    }
    return pop(&queue->output_stack);
}

三、完整实现代码

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100

// 栈结构体
typedef struct {
    int data[MAX_SIZE];
    int top;
} Stack;

// 初始化栈
void initStack(Stack* s) {
    s->top = -1;
}

// 判断栈空
int isStackEmpty(Stack* s) {
    return s->top == -1;
}

// 判断栈满
int isStackFull(Stack* s) {
    return s->top == MAX_SIZE - 1;
}

// 入栈
void push(Stack* s, int val) {
    if (isStackFull(s)) {
        printf("Stack Overflow\n");
        exit(1);
    }
    s->data[++s->top] = val;
}

// 出栈
int pop(Stack* s) {
    if (isStackEmpty(s)) {
        printf("Stack Underflow\n");
        exit(1);
    }
    return s->data[s->top--];
}

// 队列结构体(包含两个栈)
typedef struct {
    Stack input_stack;
    Stack output_stack;
} Queue;

// 初始化队列
void initQueue(Queue* q) {
    initStack(&q->input_stack);
    initStack(&q->output_stack);
}

// 入队操作
void enQueue(Queue* q, int val) {
    if (isStackFull(&q->input_stack)) {
        printf("Queue is Full\n");
        return;
    }
    push(&q->input_stack, val);
}

// 出队操作
int deQueue(Queue* q) {
    if (isStackEmpty(&q->output_stack)) {
        if (isStackEmpty(&q->input_stack)) {
            printf("Queue is Empty\n");
            exit(1);
        }
        // 转移全部元素
        while (!isStackEmpty(&q->input_stack)) {
            push(&q->output_stack, pop(&q->input_stack));
        }
    }
    return pop(&q->output_stack);
}

// 获取队首元素
int queueFront(Queue* q) {
    if (isStackEmpty(&q->output_stack)) {
        while (!isStackEmpty(&q->input_stack)) {
            push(&q->output_stack, pop(&q->input_stack));
        }
    }
    return q->output_stack.data[q->output_stack.top];
}

// 判断队列是否为空
int isQueueEmpty(Queue* q) {
    return isStackEmpty(&q->input_stack) && isStackEmpty(&q->output_stack);
}

四、复杂度分析

4.1 时间复杂度

操作

时间复杂度

摊还复杂度

入队

O(1)

O(1)

出队

O(n)

O(1)

摊还分析:每个元素最多经历两次入栈和两次出栈操作,总体时间复杂度保持O(1)

4.2 空间复杂度

O(n),需要维护两个栈的存储空间

五、测试与验证

代码语言:javascript
代码运行次数:0
复制
int main() {
    Queue q;
    initQueue(&q);

    // 测试用例
    enQueue(&q, 1);
    enQueue(&q, 2);
    enQueue(&q, 3);

    printf("Dequeue: %d\n", deQueue(&q)); // 应输出1
    printf("Front: %d\n", queueFront(&q)); // 应输出2

    enQueue(&q, 4);
    
    printf("Dequeue: %d\n", deQueue(&q)); // 应输出2
    printf("Dequeue: %d\n", deQueue(&q)); // 应输出3
    printf("Dequeue: %d\n", deQueue(&q)); // 应输出4

    return 0;
}

六、应用场景与扩展思考

6.1 典型应用
  • 线程安全的队列实现
  • 函数调用层次限制场景
  • 某些编程面试题(如LeetCode 232题)
6.2 优化方向
  1. 延迟转移策略:减少栈间元素转移次数
  2. 动态扩容:实现自动扩容的栈结构
  3. 线程安全:添加互斥锁实现多线程安全
6.3 反向思考

如何用队列实现栈?(LeetCode 225题)

通过这种双栈结构的设计,我们成功突破了数据结构固有特性的限制,实现了不同数据结构间的特性转换。这种设计思路体现了计算机科学中"用简单组件构建复杂系统"的典型方法论,建议读者可以尝试实现其他数据结构间的相互模拟来加深理解。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、数据结构基础回顾
    • 1.1 栈(Stack)
    • 1.2 队列(Queue)
  • 二、问题分析与解决方案
    • 2.1 核心矛盾
    • 2.2 双栈方案
    • 2.3 算法流程
  • 三、完整实现代码
  • 四、复杂度分析
    • 4.1 时间复杂度
    • 4.2 空间复杂度
  • 五、测试与验证
  • 六、应用场景与扩展思考
    • 6.1 典型应用
    • 6.2 优化方向
    • 6.3 反向思考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档