栈的基础知识

2023-05-16

0. 简介

最近在自己编写一些小的算法的时候,深感自己的算法过于臃肿。碰巧Datawhale在新的一期组队学习中组织了数据结构与算法的课程学习。于是就参加了,再次感谢Datawhale~~

首先跟大家分享一下两个自己感觉比较好的学习资料,一个是 算法通关手册 ,也是Datawhale在本次组队学习中的学习资料;一个是B站上的视频 【北京大学】数据结构与算法Python版(完整版),老师讲的特别棒(也难得有Python版的数据结构课程,哈哈~)。

1. 栈的简介

栈是数据结构中常见的一种数据存储方式。栈的全称叫做 堆栈(Stack)。栈是一种线性表数据结构,是一种只允许在表的一端进行插入和删除操作的线性表。个人认为,栈的最大特点就是后进先出(Last In First Out)简称为 「LIFO 结构」。这一特点主要体现在栈的 入栈出栈 操作中,即最后进入栈的数据会被第一个取出来,具体操作如下图所示:

在这里插入图片描述

1.1 栈的存储方式

和之前介绍的数组一样,栈的存储主要有两种方式:

  1. 顺序存储:顺序栈,即堆栈的顺序存储结构。利用一组地址连续的存储单元依次存放自栈底到栈顶的元素,同时使用指针 top 指示栈顶元素在顺序栈中的位置。
  2. 链式存储:链式栈,即堆栈的链式存储结构。利用单链表的方式来实现堆栈。栈中元素按照插入顺序依次插入到链表的第一个节点之前,并使用栈顶指针 top 指示栈顶元素, top 永远指向链表的头节点位置。

算法通关手册 中分别给出了两种存储方式的代码实现

  • 顺序栈

其主要的思想是利用了Python中已经有的数组来构建顺序栈,并始终遵循 LIFO 原则。

代码如下:

class Stack:
    # 初始化空栈
    def __init__(self, size=100):
        self.stack = []
        self.size = size
        self.top = -1    
        
    # 判断栈是否为空
    def is_empty(self):
        return self.top == -1
    
    # 判断栈是否已满
    def is_full(self):
        return self.top + 1 == self.size
    
    # 入栈操作
    def push(self, value):
        if self.is_full():
            raise Exception('Stack is full')
        else:
            self.stack.append(value)
            self.top += 1
    
    # 出栈操作
    def pop(self):
        if self.is_empty():
            raise Exception('Stack is empty')
        else:
            self.top -= 1
            self.stack.pop()
    
    # 获取栈顶元素
    def peek(self):
        if self.is_empty():
            raise Exception('Stack is empty')
        else:
            return self.stack[self.top]
  • 链式栈

链式栈的构造引用了之前介绍的节点,并始终遵循 LIFO 原则

代码如下:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None
        
class Stack:
    # 初始化空栈
    def __init__(self):
        self.top = None
    
    # 判断栈是否为空
    def is_empty(self):
        return self.top == None
    
    # 入栈操作
    def push(self, value):
        cur = Node(value)
        cur.next = self.top
        self.top = cur
    
    # 出栈操作
    def pop(self):
        if self.is_empty():
            raise Exception('Stack is empty')
        else:
            cur = self.top
            self.top = self.top.next
            del cur
    
    # 获取栈顶元素
    def peek(self):
        if self.is_empty():
            raise Exception('Stack is empty')
        else:
            return self.top.value

1.2 栈的简单应用

我们通过一道 Leetcode 试题来看一下栈的应用。这道题在 算法通关手册 和 【北京大学】数据结构与算法Python版(完整版)中都有提到。本文中采用的是 算法通关手册 的代码。
题目的论述如下:

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s。
要求:判断括号是否匹配。如果匹配,返回 True,否则返回 False。

解题思路为:

  • 先判断一下字符串的长度是否为偶数。因为括号是成对出现的,所以字符串的长度应为偶数,可以直接判断长度为奇数的字符串不匹配。如果字符串长度为奇数,则说明字符串 s 中的括号不匹配,直接返回 False。
  • 使用栈 stack 来保存未匹配的左括号。然后依次遍历字符串 s 中的每一个字符。如果遍历到左括号时,将其入栈。如果遍历到右括号时,先看栈顶元素是否是与当前右括号相同类型的左括号。如果是相同类型的左括号,则令其出栈,继续向前遍历。如果不是相同类型的左括号,则说明字符串 s 中的括号不匹配,直接返回 False。
  • 遍历完,再判断一下栈是否为空。如果栈为空,则说明字符串 s 中的括号匹配,返回 True。如果栈不为空,则说明字符串 s 中的括号不匹配,返回 False。

代码如下:

class Solution:
    def isValid(self, s: str) -> bool:
        if len(s) % 2 == 1:
            return False
        stack = list()
        for ch in s:
            if ch == '(' or ch == '[' or ch == '{':
                stack.append(ch)
            elif ch == ')':
                if len(stack) !=0 and stack[-1] == '(':
                    stack.pop()
                else:
                    return False
            elif ch == ']':
                if len(stack) !=0 and stack[-1] == '[':
                    stack.pop()
                else:
                    return False
            elif ch == '}':
                if len(stack) !=0 and stack[-1] == '{':
                    stack.pop()
                else:
                    return False
        if len(stack) == 0:
            return True
        else:
            return False
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

栈的基础知识 的相关文章

随机推荐

  • 基于CUDA和TCP通信的大数据双机加速计算(CUDA加速、内存优化、TCP多机协同)

    1 环境 技术简介 1 1 程序运行环境 1 server端计算机 操作系统 xff1a Ubuntu 18 04 5 LTS 运行环境 xff1a VSCode或Bash终端 2 client端计算机 操作系统 xff1a Ubuntu
  • RGB888转换为RGB565格式

    RGB888转换为RGB565格式 RGB888用unsigned int 32位字节存储 00000000R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2
  • Keil5界面配置

    配置一 xff1a 绿色 Specification for text selection and caret line selection fore 61 00FFFF selection back 61 004000 caret for
  • Linux内核调试环境(centos+gdb+qemu)

    一 写在前面 主要介绍qemu在Centos中的安装过程 xff0c 以及遇到的一些麻烦 网上教程好多都是在Ubuntu环境下的安装 xff0c 但是公司给的环境大都是Centos xff0c 没办法花了一天的时间 xff0c 磕磕绊绊弄好
  • Linux中修改系统启动项grub

    在修改grub时看到很多资料 xff0c 上来就是直接修改 etc default grub配置文件中的GRUB DEFAULT配置项 xff0c 但是有时候修改不成功 xff0c 本文简单说明一下修改的原理 注 xff1a 根据本人机器上
  • C语言调用cJSON库解析json

    一 源代码文件下载 自己使用时可以只需要其中的cJSON c和cJSON h文件就可以了 xff0c 只需要将cJSON和自己的main文件一起编译即可 下载地址 xff1a cJSONFiles zip 互联网文档类资源 CSDN下载 二
  • Java学习记录 (一)

    使用 BufferedReader 按行读入文档内容 InputStream input file span class token operator 61 span null span class token punctuation sp
  • cmake学习5:如何将自己的库作为第三方库给别人使用

    前言 自己在使用cmake进行编译工程的时候不太了解cmake的基本使用方法 有时候出现找不到第三方库的问题也不知如何排查 因此相对cmake有个稍微系统的认识 希望能用这个强大的工具来更好的为自己的工程服务 因此总结为了几篇博客 主要参考
  • C++头文件包含顺序

    Google C 43 43 编程风格指南 对于头文件的包含顺序是这样的 xff1a Names and Order of Includes link Use standard order for readability and to av
  • VLC Web插件踩坑记录

    VLC Web插件 问题描述 近期由于工作项目组人员变动 xff0c 来到新的项目组 xff0c Leader约谈前期也不安排过多任务 xff0c 但是有一个项目中现有的问题需要解决 项目中视频在线播放功能需要支持在线播放 avi媒体格式
  • cmake添加第三方库

    主要方法 将包含目录添加到构建中 span class token function include directories span span class token punctuation span D span class token
  • UART+DMA数据传输

    DMA的概念 DMA xff08 Direct Memory Access xff09 即直接内存访问 xff0c DMA传输方式无需CPU直接控制传输 xff0c 通过硬件为RAM I O设备开辟一条直接传输数据的通路 xff0c 能使C
  • asp.net core 3.1 应用部署到国产服务器 centos7 自动启动

    首先安装依赖 xff1a 注册 Microsoft 密钥 注册产品存储库 安装必需的依赖项 sudo rpm Uvh https packages microsoft com config centos 7 packages microso
  • Visual Studio2022 离线安装包下载

    首先去官网下载引导程序 xff1a https docs microsoft com en us visualstudio install create an offline installation of visual studio vi
  • MWC-电机、电池螺旋桨搭配

    原址 xff1a http blog sina com cn s blog 402c071e0102v2xv html 电池 电机 螺旋桨搭配 1 电机 1 电机KV值 xff1a 大KV配小桨 xff0c 小KV配大桨 KV值是每1V的电
  • linux系统发送http请求示例:

    http post示例 xff1a curl H 34 Content Type application json 34 X POST d 39 34 ChannelInfo 34 34 algoList 34 34 CarDetectio
  • 博途的多步过程控制, 寄存器寻址

    1 xff0c 实际生产中 xff0c 收到的开关信号往往是短信号 脉冲 2 Step 变化的逻辑和设备的逻辑分开 Step的变化逻辑在实际中往往是设备的反馈信号决定 xff0c 在此处用定时器信号代替 定时器的触发用Step的状态触发 x
  • 栈、堆、方法区存储的内容

    堆区 1 存储的全部是对象 xff0c 每个对象都包含一个与之对应的class的信息 class的目的是得到操作指令 2 jvm只有一个堆区 heap 被所有线程共享 xff0c 堆中不存放基本类型和对象引用 xff0c 只存放对象本身 栈
  • 【verilog】UART串口发送(FPGA)

    简述核心代码仿真测试 简述 串口发送是以一定速率发送单bit数据 xff0c 通常一组数据为10bit 空闲状态为高电平 xff0c 起始位为0 xff0c 中间以低位在前的方式发送8bit数据 xff0c 终止位为1 采用计数器 cnt
  • 栈的基础知识

    0 简介 最近在自己编写一些小的算法的时候 xff0c 深感自己的算法过于臃肿 碰巧Datawhale在新的一期组队学习中组织了数据结构与算法的课程学习 于是就参加了 xff0c 再次感谢Datawhale 首先跟大家分享一下两个自己感觉比