数据结构入门:栈和队列

算法入门之基本数据结构:队列和栈 大家都知道,算法和数据结构是息息相关,学习数据结构能帮助我们更好的理解算法,理解编程,这是一种编程思想的培养;今天我们要介绍的数据结构是:队列,可以把队列想象成一个双向管道,一边进另一边出 代码示例 public class QueueDemo { public static void main(String[] args) { //1.初始化一组数据 int[] start = {1,2,3,4,5,6,7,8,9}; //2.初始化一个... 阅读详情

一、栈的基本概念

栈是一种特殊的线性表,其操作限制在固定的一端(栈顶)。这种结构遵循后进先出(LIFO)原则,常见于堆叠的盘子、函数调用等场景。关键术语包括:

  • 栈顶:允许插入和删除的一端。
  • 栈底:栈顶的对端。
  • 入栈(push):向栈顶插入元素。
  • 出栈(pop):从栈顶移除元素。
  • 取栈顶(top):获取栈顶元素但不移除。

栈的存储形式

栈的实现可分为顺序栈和链式栈:

顺序栈

通过数组实现,需预先分配连续内存空间。结构体定义如下:

typedef struct {
    datatype *data;  // 存储数组
    int size;        // 栈容量
    int top;         // 栈顶下标(初始为-1)
} seqStack;

链式栈

通过链表实现,动态分配节点内存。结构体定义如下:

typedef struct node {
    datatype data;
    struct node *next;
} node;

typedef struct {
    node *top;  // 栈顶指针
    int size;   // 元素个数
} linkStack;

基本操作实现

顺序栈操作
// 初始化栈
seqStack *initStack(int size) {
    seqStack *s = malloc(sizeof(seqStack));
    if (s) {
        s->data = malloc(sizeof(datatype) * size);
        s->size = size;
        s->top = -1;
    }
    return s;
}

// 入栈
bool push(seqStack *s, datatype data) {
    if (s->top == s->size - 1) return false;
    s->data[++s->top] = data;
    return true;
}

// 出栈
bool pop(seqStack *s, datatype *pm) {
    if (s->top == -1) return false;
    *pm = s->data[s->top--];
    return true;
}

链式栈操作
// 初始化栈
linkStack *initStack() {
    linkStack *s = malloc(sizeof(linkStack));
    if (s) {
        s->top = NULL;
        s->size = 0;
    }
    return s;
}

// 入栈
bool push(linkStack *s, datatype data) {
    node *newNode = malloc(sizeof(node));
    if (!newNode) return false;
    newNode->data = data;
    newNode->next = s->top;
    s->top = newNode;
    s->size++;
    return true;
}

// 出栈
bool pop(linkStack *s, datatype *pm) {
    if (!s->top) return false;
    node *tmp = s->top;
    *pm = tmp->data;
    s->top = tmp->next;
    free(tmp);
    s->size--;
    return true;
}

关键区别

  • 顺序栈:内存连续,容量固定,适合已知最大规模的场景。
  • 链式栈:动态扩容,内存分散,适合规模不确定的场景。

应用场景

  • 函数调用栈
  • 表达式求值(如括号匹配)
  • 浏览器历史记录(后退功能)

二、队列的基本概念

队列是一种特殊的线性表,遵循先进先出(FIFO)原则。只能在固定两端操作:

  • 队头:删除节点的一端
  • 队尾:插入节点的一端
  • 入队(enQueue()):在队尾插入节点
  • 出队(outQueue()):从队头删除节点
  • 取队头(front()):获取队头元素但不删除

循环队列(顺序存储)

循环队列通过顺序存储实现,利用数组的循环利用特性避免数据移动。需牺牲一个存储单元区分空队和满队:

  • 空队条件:front == rear
  • 满队条件:(rear + 1) % capacity == front

管理结构体示例

struct seqQueue {
    datatype *data;  // 数组入口
    int capacity;     // 总容量
    int front;        // 队头下标
    int rear;         // 队尾下标
};

核心操作代码

// 初始化
seqQueue* initQueue(int cap) {
    seqQueue *q = malloc(sizeof(seqQueue));
    q->data = malloc(cap * sizeof(datatype));
    q->capacity = cap;
    q->front = q->rear = 0;
    return q;
}

// 入队
bool enQueue(seqQueue *q, datatype val) {
    if ((q->rear + 1) % q->capacity == q->front) 
        return false;
    q->data[q->rear] = val;
    q->rear = (q->rear + 1) % q->capacity;
    return true;
}

// 出队
bool outQueue(seqQueue *q, datatype *val) {
    if (q->front == q->rear) 
        return false;
    *val = q->data[q->front];
    q->front = (q->front + 1) % q->capacity;
    return true;
}

链式队列

链式队列通过链表实现,管理结构体保存队头、队尾指针及元素数量:

结构体定义

typedef struct node {
    datatype data;
    struct node *next;
} node;

typedef struct {
    node *front;  // 队头指针
    node *rear;   // 队尾指针
    int size;     // 元素数量
} linkQueue;

核心操作代码

// 入队
bool enQueue(linkQueue *q, datatype val) {
    node *newNode = malloc(sizeof(node));
    newNode->data = val;
    newNode->next = NULL;
    
    if (q->size == 0) 
        q->front = q->rear = newNode;
    else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
    q->size++;
    return true;
}

// 出队
bool outQueue(linkQueue *q, datatype *val) {
    if (q->size == 0) 
        return false;
    *val = q->front->data;
    node *tmp = q->front;
    q->front = q->front->next;
    free(tmp);
    q->size--;
    if (q->size == 0) 
        q->rear = NULL;
    return true;
}

    【数据结构|C语言版】栈和队列 各位小伙伴大家好!上次小编给大家讲解了数据结构中的重要基础:算法效率和复杂度分析,接下来我们讲解一下栈和队列!【知识框架】以上就是小编对栈和队列的讲解。如果觉得小编讲的还可以,还请一键三连。互三必回!持续更新中~! 阅读详情

    相关推荐

    告别环境配置焦虑:在Win10的Ubuntu子系统里搞定CSAPP实验环境(附32/64位库编译指南)

    本文详细介绍了如何在Win10的Ubuntu子系统中搭建CSAPP实验环境,包括WSL 2的安装与配置、32/64位库的编译指南以及高效开发工具链的设置。通过优化WSL性能和使用实用技巧,开发者可以轻松应对CSAPP实验中的环境配置问题,提升学习效率。

    weixin_30443813的博客 296

    [入门必看]数据结构3.3:栈和队列的应用

    数据结构3.3:栈和队列的应用

    m0_58991879的博客 688

    CANdb++ Editor实战:5步搞定DBC文件信号布局与字节对齐(附常见错误排查)

    本文详细介绍了使用CANdb++ Editor进行DBC文件信号布局与字节对齐的实战方法。通过五步法,深入解析Intel与Motorola字节序差异、跨字节信号布局规则,并借助Layout视图等工具,帮助工程师高效解决信号错位、数据解析错误等常见问题,确保CAN网络通信的准确性与可靠性。

    solidity8miner的博客 695

    【C++从入门到入土】第十六篇:再谈数据结构--栈和队列

    栈和队列 文章目录栈和队列栈(stack)练习1练习2栈的模拟实现队列 栈(stack) 栈是一个后进先出的数据结构,本身是一个半封闭的容器; 如果想要查看栈当中的每一个元素,它里面是没有一个迭代器的支持的,本身不支持遍历,不允许在中间位置进行任何的操作; 因此只能在一端进行数据的插入与删除,所以想要访问元素,只能看到栈顶的元素; 练习1 155.最小栈 练习2 JZ21.栈的压入弹出序列 栈的模拟实现 队列 ...

    李憨憨 159

    从零上手HiAgent:构建能听懂指令的智能体框架实战指南

    智能体(Agent)作为人工智能领域的重要范式,正从传统的预设流程自动化转向以目标驱动的自主规划与执行。其核心原理在于利用大语言模型(LLM)作为决策大脑,通过任务规划、工具调用与记忆机制,将模糊的自然语言指令转化为可执行的工作流。这一技术显著提升了人机协作的效率和自然度,其价值在自动化办公、数据分析与智能流程编排等场景中尤为突出。本文聚焦于HiAgent这一具体框架,深入解析其作为智能体开发平台的核心架构,涵盖规划器、执行器、工具集等关键组件,并提供从环境配置、自定义工具开发到复杂任务链构建的完整工程实践

    weixin_29266007的博客 889

    【FPGA教程案例100】深度学习1——基于CNN卷积神经网络的手写数字识别纯Verilog实现,使用mnist手写数字数据库

    MNIST 数据库有一个 60,000 示例的训练集,还有一个 10,000 示例的测试集。这些数字已在大小方面规范化,在固定大小的图像中居中。如下图所示:我们任意选择0~9是个数字,将其转化为数字:0_0.txt1_0.txt2_0.txt3_0.txt4_0.txt5_0.txt6_0.txt7_0.txt8_0.txt9_0.txt。

    FPGA/MATLAB学习教程/源码/项目合作开发 7830

    数据结构与算法——栈和队列

    栈和队列是两种重要的线性结构,本篇文章详细总结了数据结构与算法中栈和队列的终点知识,并且结合代码片段实现其基本操作,干货满满,每一句话都是重点,希望能给更多的小伙伴在学习数据结构与算法时带来一定帮助...

    小田是个程序员的博客欢迎你的到来呀~ 2万+

    【通信】多径衰落信道的matlab仿真

    1 简介 2 部分代码 clearf_c=1e3; %carrier frequency(no modulation)time_1 = (linspace (0, 10, 1000)); %timesignal_in = sin (2 * pi *f_c* time_1); %sine wave plot (time_1, signal_in, 'b');grid on;

    qq_59747472的博客 1383

    【数据结构】栈和队列

    然后,我们可以使用STTop取出栈(st)中的数据,进行对栈(s)的左右括号的匹配,如果匹配不成功,则返回false,直到栈(s)为空时,过程结束。若节点大于一个,那我们可以创建一个QNode*的next节点指向队头指向的下一个节点,然后再将队头的节点free,再重新将队头的节点改为next指针指向的新节点。首先,我们来了解一种新的数据结构——栈。将数据导入栈中,首先,将空间进行扩容(防止空间不足引起的越界访问),并将扩容后的空间传给数组a,然后,再于新空间进行导入数据的操作,结尾记得改变新栈的个数。

    2301_81348661的博客 3766

    提取游戏音频文件.bnk

    bnk其实是一种对音频的加密方式,一个.bnk文件中通常包含了多个语音文件,一般可以使用Wwise-Unpacker来解码.bnk格式文件该工具命名没有规律,需要手动整理文件名。市面上很多的游戏都把音频文件打成.bnk文件(比如永劫无间),用这种方式可以将你想要的游戏的音频都提取出来,本文内容仅供自己娱乐。

    类人_猿的博客 8748

    Centos 7 Linux 离线安装使用 MySQL 5.7:下载、安装、配置、使用

    本文详细介绍了在 CentOS 7 系统下离线安装 MySQL 5.7 的完整流程,包括环境准备、安装包下载、用户与目录配置、数据库初始化、服务启动与自启设置、root 密码修改、远程访问开启及防火墙配置等关键步骤,并提供了本地与远程客户端(如 Navicat、DBeaver)的连接使用方法,适合无网络环境下的数据库部署参考。

    寒水馨 · 轻量级技术文档 · hanshuixin.org 6112

    [详解栈和队列]数据结构之栈与队列

    ✅作者简介:大家好,我是Philosophy7?让我们一起共同进步吧!🏆 📃个人主页:Philosophy7的csdn博客 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍+收藏⭐️+留言📝支持一下博>主哦🤞 文章目录栈和队列1.物理结构和逻辑结构2.什么是栈2.1栈的基本操作3.什么是队列队列的基本操作小结 栈和队列 1.物理结构和逻辑结构 再了解栈和队列之前,我们要先知道什么是逻辑结构和物理结构。 逻辑结构: 按照逻辑结构划分:数据结.

    Philosophy7的博客 4195

    Opencv计算机视觉PPT-算法篇

    01 02 03 04 05 06 07 08 09 010 011 012 013 014 015 016 017 018

    Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 204

    数据结构——栈和队列

    本文详细介绍的栈和队列的实现方式,更是重点提到了4个关于栈和队列的OJ题:分别是设计循环队列,用栈实现队列,用队列实现栈,有效的括号。

    fax_player的博客 6219

    VC中sqlite的使用

    在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

    计算机控制技术及应用

    《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

    【数据结构】栈和队列超详细讲解

    我们已经学习了顺序表、链表、数组等数据结构,今天我们再来认识一下栈和队列两种新的数据结构,一起来看看吧~

    Become Mad的博客 3101

    ET2012新版免狗免安装绿色软件

    ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

    数据结构:栈和队列

    栈和队列的详细介绍及其实现步骤(附带图解和完整代码)。

    Yikefore的博客 1377

    【Java数据结构】实现栈和队列

    【Java数据结构】实现栈和队列

    yanxiang3306 6609

    数据结构实验报告—栈和队列

    数据结构实验报告,栈,队列,C语言

    VLOKL的博客 4422

    数据结构—栈和队列

    栈是一种只能在一端进行插入或删除操作的线性表。在表中允许进行插入、删除操作的一端称为栈顶。栈顶的当前位置是动态的,由一个称为栈顶指针的位置指示器来指示。表的另一端称为栈底。当栈中没有数据元素时称为空栈。栈的插入操作通常称为进栈或入栈,栈的删除操作通常称为退栈或出栈。栈的主要特点是"先进后出",即后进栈的元素先出栈。每次进栈的元素都放在原当前栈顶元素之前成为新的栈顶元素,每次出栈的元素,都是原当前栈顶元素。栈也成为后进先出表。

    2303_80188300的博客 1850

    【数据结构】栈和队列&&OJ练习

    栈和队列的实现及其OJ练习

    大三小白C++进阶之路 1726

    【数据结构】:栈和队列

    假设某个栈S=(a1,a2,a3,a4,a5,a6),如图所示,则a1,为栈底元素,a6为栈顶元素。队列和栈一样,队列的实现一般也可以使用数组或链表,而用数组实现的队列通常设计成循环队列,较为复杂(在我之后的一篇关于栈和队列练习题中有关于循环队列的题,我将在之后的文章中讲解,感兴趣的可以关注期待一下),这里重点讲解用链表实现的队列。入栈的时候我们要先考虑数组满的情况,如果数组满了,我们就要为数组扩容,如果我们直接让原来的指针ps->a指向扩容的数组地址,扩容失败ps->a就会直接变成空指针,

    2301_82347435的博客 1056

    数据结构 栈和队列

    5. 访问效率:顺序存储结构的元素在内存中是连续存储的,对于 CPU 缓存等硬件有较好的利用效率,因此在访问速度上可能更快。特殊矩阵的压缩存储可以大幅减少存储空间的占用,提高存储效率,并在某些情况下加速矩阵的运算和操作。需要注意的是,多维数组的存储方式可能会影响程序的性能,特别是对于大型多维数组和对数组访问频繁的场景。总之,栈和队列都是重要的数据结构,在不同的应用场景中发挥着关键的作用。栈和队列都是常见的数据结构,可以使用不同的存储结构进行实现,包括顺序存储结构和链式存储结构。函数判断栈是否为空。

    qq_52847866的博客 4938
    上一篇: 关于如何解决LVGL以及Keil中编译时间过长的问题
    下一篇: 网络编程学习(man函数手册)
    赶路中
    博客等级 码龄4年 123粉丝 9原创
    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    个

    红包个数最小为10个

    元

    红包金额最低5元

    当前余额3.43元 前往充值 >
    需支付:10.00元
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付元
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值