栈与队列:数据结构中的 孪生兄弟 的本质差异

栈与队列:数据结构中的 孪生兄弟 的本质差异

个人主页-爱因斯晨

文章专栏-数据结构

在这里插入图片描述

文章目录

    • 个人主页-爱因斯晨
    • 文章专栏-数据结构
    • 1. 引言
    • 2. 栈和队列的概念界定
      • 2.1 栈
      • 2.2 队列
    • 3. 栈和队列的核心差异
    • 4. 栈的 C 语言实现
      • 4.1 栈的结构体定义
      • 4.2 栈的基本操作函数
        • 4.2.1 初始化栈
        • 4.2.2 判断栈是否为空
        • 4.2.3 判断栈是否已满
        • 4.2.4 入栈操作
        • 4.2.5 出栈操作
    • 5. 队列的 C 语言实现
      • 5.1 队列的结构体定义
      • 5.2 队列的基本操作函数
        • 5.2.1 初始化队列
        • 5.2.2 判断队列是否为空
        • 5.2.3 判断队列是否已满
        • 5.2.4 入队操作
        • 5.2.5 出队操作
    • 6. 栈和队列操作的差异总结
    • 7. 结论
    • 7. 结论

1. 引言

在数据结构中,栈和队列是两种重要的线性结构,它们在数据的存储和操作方式上有着显著的不同,各自适用于不同的应用场景。本文将详细阐述栈和队列的概念、差异,并通过 C 语言实现示例,帮助读者深入理解这两种数据结构。

2. 栈和队列的概念界定

2.1 栈

栈是一种遵循 “后进先出”(Last In First Out,LIFO)原则的线性数据结构。它只允许在一端进行插入和删除操作,这一端被称为栈顶,另一端则被称为栈底。

例如,日常生活中叠放的盘子,最后放在上面的盘子可以最先被拿走,这就是栈的典型体现。

2.2 队列

队列是一种遵循 “先进先出”(First In First Out,FIFO)原则的线性数据结构。它允许在一端进行插入操作(队尾),在另一端进行删除操作(队头)。

就像在银行柜台前排队办理业务的人群,先排队的人先办理业务,后排队的人需要等待前面的人办理完毕,这符合队列的特性。

3. 栈和队列的核心差异

对比项队列
操作原则后进先出(LIFO)先进先出(FIFO)
操作端仅在栈顶进行插入和删除在队尾插入,在队头删除
应用场景函数调用、表达式求值、括号匹配等任务调度、缓冲处理、广度优先搜索等

4. 栈的 C 语言实现

4.1 栈的结构体定义

#include<stdio.h>#include<stdlib.h>#defineSTACK_SIZE50// 栈的最大容量typedefstruct{int data[STACK_SIZE];// 用于存储栈中元素的数组int top;// 栈顶指针,指向栈顶元素所在位置} Stack;

4.2 栈的基本操作函数

4.2.1 初始化栈
// 功能:初始化栈,使栈为空// 参数:stack - 指向栈结构体的指针voidInitStack(Stack *stack){ stack->top =-1;// 栈顶指针为-1时,表示栈为空}
4.2.2 判断栈是否为空
// 功能:判断栈是否为空// 参数:stack - 指向栈结构体的指针// 返回值:1 - 栈为空;0 - 栈不为空intIsEmpty(Stack *stack){return stack->top ==-1;}
4.2.3 判断栈是否已满
// 功能:判断栈是否已满// 参数:stack - 指向栈结构体的指针// 返回值:1 - 栈已满;0 - 栈未满intIsFull(Stack *stack){return stack->top == STACK_SIZE -1;}
4.2.4 入栈操作
// 功能:向栈顶插入元素// 参数:stack - 指向栈结构体的指针;value - 要插入的元素值// 返回值:1 - 入栈成功;0 - 入栈失败(栈已满)intPush(Stack *stack,int value){if(IsFull(stack)){return0;} stack->top++; stack->data[stack->top]= value;return1;}
4.2.5 出栈操作
// 功能:从栈顶删除元素,并返回该元素值// 参数:stack - 指向栈结构体的指针;value - 用于存储出栈元素值的指针// 返回值:1 - 出栈成功;0 - 出栈失败(栈为空)intPop(Stack *stack,int*value){if(IsEmpty(stack)){return0;}*value = stack->data[stack->top]; stack->top--;return1;}

5. 队列的 C 语言实现

5.1 队列的结构体定义

#include<stdio.h>#include<stdlib.h>#defineQUEUE_SIZE50// 队列的最大容量typedefstruct{int data[QUEUE_SIZE];// 用于存储队列中元素的数组int front;// 队头指针,指向队头元素int rear;// 队尾指针,指向队尾元素的下一个位置} Queue;

5.2 队列的基本操作函数

5.2.1 初始化队列
// 功能:初始化队列,使队列为空// 参数:queue - 指向队列结构体的指针voidInitQueue(Queue *queue){ queue->front =0; queue->rear =0;}
5.2.2 判断队列是否为空
// 功能:判断队列是否为空// 参数:queue - 指向队列结构体的指针// 返回值:1 - 队列为空;0 - 队列不为空intIsQueueEmpty(Queue *queue){return queue->front == queue->rear;}
5.2.3 判断队列是否已满
// 功能:判断队列是否已满// 参数:queue - 指向队列结构体的指针// 返回值:1 - 队列已满;0 - 队列未满intIsQueueFull(Queue *queue){return(queue->rear +1)% QUEUE_SIZE == queue->front;}
5.2.4 入队操作
// 功能:向队尾插入元素// 参数:queue - 指向队列结构体的指针;value - 要插入的元素值// 返回值:1 - 入队成功;0 - 入队失败(队列已满)intEnQueue(Queue *queue,int value){if(IsQueueFull(queue)){return0;} queue->data[queue->rear]= value; queue->rear =(queue->rear +1)% QUEUE_SIZE;return1;}
5.2.5 出队操作
// 功能:从队头删除元素,并返回该元素值// 参数:queue - 指向队列结构体的指针;value - 用于存储出队元素值的指针// 返回值:1 - 出队成功;0 - 出队失败(队列为空)intDeQueue(Queue *queue,int*value){if(IsQueueEmpty(queue)){return0;}*value = queue->data[queue->front]; queue->front =(queue->front +1)% QUEUE_SIZE;return1;}

6. 栈和队列操作的差异总结

操作队列
插入位置栈顶队尾
删除位置栈顶队头
操作原则体现每次插入和删除都在栈顶,体现 LIFO插入在队尾、删除在队头,体现 FIFO
指针变化仅栈顶指针变化队头和队尾指针均可能变化(循环队列中通过取模实现循环)

7. 结论

栈和队列作为两种重要的线性数据结构,由于其操作规则的不同,在实际应用中有着不同的用途。栈适用于需要 “后进先出” 特性的场景,如函数调用、表达式求值等;队列适用于需要 “先进先出” 特性的场景,如任务调度、缓冲处理等。

|
| 指针变化 | 仅栈顶指针变化 | 队头和队尾指针均可能变化(循环队列中通过取模实现循环) |

7. 结论

栈和队列作为两种重要的线性数据结构,由于其操作规则的不同,在实际应用中有着不同的用途。栈适用于需要 “后进先出” 特性的场景,如函数调用、表达式求值等;队列适用于需要 “先进先出” 特性的场景,如任务调度、缓冲处理等。

通过 C 语言的实现,可以更清晰地看到它们在存储结构和操作方式上的差异,理解这些差异对于正确选择和使用这两种数据结构至关重要。

Read more

C++学习之旅【C++伸展树介绍以及红黑树的实现】

C++学习之旅【C++伸展树介绍以及红黑树的实现】

🔥承渊政道:个人主页 ❄️个人专栏: 《C语言基础语法知识》《数据结构与算法》 《C++知识内容》《Linux系统知识》 ✨逆境不吐心中苦,顺境不忘来时路!🎬 博主简介: 引言:前篇文章,小编已经介绍了关于C++AVL树的实现!相信大家应该有所收获!接下来我将带领大家继续深入学习C++的相关内容!本篇文章着重介绍关于C++伸展树介绍以及红黑树的实现!伸展树与红黑树是两类极具代表性的BBST,且在工程实践中各有不可替代的价值:伸展树摒弃了"严格平衡”的执念,通过“伸展”操作将最近访问的节点移至根节点,利用“局部性原理”优化频繁访问的场景,实现均摊O(logn)的时间复杂度,适合缓存、热点数据查询等场景;红黑树则通过给节点着色并遵守严格的颜色规则,确保树的最长路径不超过最短路径的两倍,以 “弱平衡” 换稳定的最坏O(logn)性能,是C++ STL 中 std::map、std:

By Ne0inhk
文科生封神!Python+AI 零门槛变现:3 天造 App,指令即收入(附脉脉 AI 沙龙干货)

文科生封神!Python+AI 零门槛变现:3 天造 App,指令即收入(附脉脉 AI 沙龙干货)

🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 文章目录: * 一、前言:打破“AI是理科生专属”的迷思 * 二、行业新趋势:为什么文科生学Python+AI更有优势? * 2.1 文科生 vs 理科生:AI时代的核心竞争力对比 * 2.2 核心变现逻辑:靠Python+AI,“指令即收入” * 三、Python+AI零基础学习路径(文科生专属版) * 3.1 学习路径流程图 * 3.2 分阶段学习核心内容(新颖且落地) * 阶段1:Python核心基础(7天)—— 只学“AI开发必备” * 阶段2:AI大模型交互(10天)

By Ne0inhk
Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践

Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践

🌟 Python中的"=="与"is":深入解析与Vibe Coding时代的优化实践 * 1. 🧐 `==`与`is`的本质区别 * 2. 🕵️‍♂️ `is`判断对象身份 - 数组与常量池案例 * 案例1:列表对象的身份 * 案例2:小整数常量池 * 案例3:字符串驻留 * 3. 🔍 `==`与`__eq__`魔法函数 * 4. 🔎 类型判断的正确姿势:使用`is` * 5. 🚀 Vibe Coding时代的提示词优化 * 场景1:解释概念 * 场景2:代码生成 * 场景3:调试帮助 * 📊 对比总结表 * 💡 实际应用建议 * 🌈 结语 在Python的奇妙世界中,==和is这两个看似简单的操作符常常让初学者感到困惑。它们如同双胞胎,外表相似却性格迥异。本文将带你深入探索它们的区别,并通过生动的案例和图表展示它们的应用场景,

By Ne0inhk

OpenSpiel进阶教程:用C++与Python实现自定义博弈算法

OpenSpiel进阶教程:用C++与Python实现自定义博弈算法 【免费下载链接】open_spielOpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games. 项目地址: https://gitcode.com/gh_mirrors/op/open_spiel OpenSpiel是一个强大的博弈算法研究框架,提供了丰富的环境和算法支持。本文将带你深入了解如何在OpenSpiel中使用C++和Python实现自定义博弈算法,从基础架构到实际代码示例,助你快速掌握博弈算法开发技巧。 🎮 自定义博弈算法的核心架构 在开始编写代码前,我们需要理解OpenSpiel中博弈算法的基本架构。OpenSpiel将博弈问题抽象为信息状态(Information State) 和策略(Policy) 的交互,算法通过优化策略来最大化预期收益。 图1:

By Ne0inhk