堆和栈的区别以及栈的顺序存储和链式存储—Python数据结构(三)

news2024/11/26 2:43:22

一、栈

1. 定义

栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),

允许进行操作的一端称为”栈顶“,另一固定端称为”栈底“,当栈中没有元素时称为”空栈“。

2. 特点

  • 栈只能在一端进行操作。

  • 栈模型具有先进后出,或者叫后进先出的规律。

在这里插入图片描述

3. 对象和引用

Python中有对象和引用的概念,他们是两个重要的概念,并且它们之间存在着密切的关系。例如
a = 456
b=789
c=knm


变量a是对对象456的引用
变量b是对对象789的引用
变量c是对对象knm的引用
在这里插入图片描述
简单来说,
对象是Python中存储数据和执行操作的基本单位。可以将对象看作是内存中分配的一块区域,包含了数据值以及与该对象相关的操作和方法。在Python中,几乎所有的数据都是以对象的形式存在,包括整数、浮点数、字符串、列表、字典等。

每个对象都有一个唯一的标识符(ID),可以通过id()函数来获取。这个标识符在对象的生命周期内是不变的,它类似于对象在内存中的地址。两个对象的标识符相同,则表明它们指向同一个对象。

引用是指向对象的指针或者名称,用于访问和操作对象。在Python中,我们可以使用变量来创建引用。当我们将一个对象赋值给一个变量时,实际上是将该对象的引用赋给了这个变量。多个变量可以引用同一个对象,即多个引用可以指向同一个对象。

4. 堆和栈的区别与联系

堆的定义:

堆是一种动态分配内存的方式,用于存储对象和数据结构。堆中的内存空间是动态分配的,它可以在程序运行时申请和释放。堆中存储的对象通常由引用变量来访问,而引用本身存储在栈中。在堆中申请的内存需要手动释放,否则可能导致内存泄露。
简单说

栈是用来存储局部变量和函数调用信息的,即存放的是对象的地址,而不是对象本体
堆是用来存储动态分配的对象的,即存放的是具体的对象,在堆中,Python为其分配内存空间,此地址就是对象在内存中的地址。

在这里插入图片描述

堆和栈的区别

  • 数据结构:
    堆:堆是一种动态分配的内存结构,存储的是对象和数据结构。在堆中存储的对象可以通过引用来访问和操作。
    栈:栈是一种后进先出(LIFO)的数据结构。它用于存储局部变量、函数调用信息和临时数据等。栈的大小是固定的,由操作系统预先定义。
  • 分配方式:
    堆:堆内存的分配和释放是动态的,通过特定的内存管理机制(如垃圾回收器)进行管理。堆内存的分配通常使用new关键字或者其他动态内存分配函数。
    栈:栈内存的分配和释放是自动的,由编译器和运行时环境负责管理。每当有一个函数被调用时,该函数的局部变量会被分配到栈上,函数执行完毕后会自动释放。
  • 大小限制:
    堆:堆的大小是相对较大的,并且受到可用内存的限制。在堆中可以动态地分配和释放内存空间。
    栈:栈的大小是固定的,在程序运行前就已经确定。通常由操作系统设置,默认情况下较小。
  • 生命周期:
    堆:在堆上创建的对象可以长时间存在,直到被垃圾回收器回收。因此,堆上的对象的生命周期相对较长。
    栈:栈上的变量的生命周期较短。当一个函数调用结束后,其局部变量会被自动销毁。
  • 访问方式:
    堆:堆中的对象通过引用来访问和操作。多个引用可以指向同一个堆上的对象。
    栈:栈中的对象通过栈指针(ESP)来访问。栈指针会随着函数的调用和返回而不断变化。

总结起来,堆和栈是两种不同的内存结构。堆用于存储对象和数据结构,具有动态分配和释放内存的能力;而栈用于存储局部变量、函数调用信息等,具有固定大小和自动管理内存的特性。了解堆和栈的区别有助于编写高效、安全的代码,并且更好地理解Python中的内存管理机制。

5. 栈的代码实现

栈的操作有入栈(压栈),出栈(弹栈),判断栈的空满等操作。

  • 顺序存储代码实现sstack.py

  • 链式存储代码实现lstack.py

栈的顺序存储模型


"""
栈模型的顺序存储
思考总结:
1. 列表即顺序存储,但功能多,不符合栈的模型特征
2. 利用列表,将其封装,提供接口方法
"""


# 自定义异常
class StackError(Exception):
    pass


# 顺序栈类
class SStack:
    def __init__(self):
        self._elems = []

    # 判断列表为空
    def is_empty(self):
        return self._elems == []

    # 入栈
    def push(self, val):
        self._elems.append(val)

    # 出栈
    def pop(self):
        if self.is_empty():
            raise StackError("Stack is empty")
        return self._elems.pop()

    # 查看栈顶元素
    def top(self):
        if self.is_empty():
            raise StackError("Stack is empty")
        return self._elems[-1]


if __name__ == "__main__":
    s1 = SStack()  # 初始化
    s1.push(10)
    s1.push(30)
    s1.push(50)
    while not s1.is_empty():
        print(s1.pop())

'''
面试题:已知,一个堆栈的入栈顺序是1,2,3,下列不可能出现的出栈的顺序的是:
3,1,2


'''

栈的链式存储模型

"""
栈的链式栈
思路分析:
1. 源于链表结构
2. 封装栈的操作方法 | 入栈出栈,栈空,栈顶元素。
3. 链表的开头作为栈顶?(不用每次遍历)
"""


# 自定义异常
class StackError(Exception):
    pass


# 创建节点类
class Node:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next


# 链式栈操作
class LStack:
    def __init__(self):
        # 标记栈的栈顶位置
        self._top = None

    def is_empty(self):
        return self._top is None

    def push(self, val):
        self._top = Node(val, self._top)

    def pop(self):
        if self._top is None:
            raise StackError("Stack is empty")
        value = self._top.val
        self._top = self._top.next
        return value


if __name__ == "__main__":
    ls = LStack()
    ls.push(20)
    ls.push(30)
    ls.push(10)
    print(ls.pop())


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/782361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于jeecg-boot的任务甘特图显示

更多功能看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 基于项目的任务显…

Redis项目 PART1

第一部分:含注册登入商户查询(使用缓存) 一、注册登入 1.1 session共享问题 使用redis而不用传统的session的原因(session共享问题):每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat&#x…

网络子系统学习3:网络访问层

目录 网络访问层 网络设备的表示 数据结构 注册网络设备 接收分组 传统方法 对高速接口的支持 发送分组 网络访问层 网络实现的第一层,即网络访问层。该层主要负责在计算机之间传输信息,与网卡的设备驱动程序直接协作。 本次不会讲驱动程序的设计…

全面助力AI人工智能在科研、教学与实践技能

目录 模块一 编程入门与进阶提高 模块二 科研数据可视化 模块三 信息检索与常用科研工具 模块四 科技论文写作与技巧 模块五 数据预处理与特征工程 模块六 多元线性回归 模块七 机器学习 模块八 深度学习 模块九 答疑讨论 更多推荐 在人工智能领域进行研究和深耕&…

PCB封装设计指导(十二)画出器件禁布,过孔走线禁布

PCB封装设计指导(十二)画出器件禁布,过孔走线禁布 对于分离器件或者Datasheet中有标注出走线或者过孔禁布,在封装中需要把这些信息体现出来,如何添加,见如下说明 1. 一般来讲,只有分离器件,比如电阻,电容,晶振才会在中间加上route keepout 和via keepout Via keep o…

Qt与opencv学习记录2

我希望把这篇文章中的效果实现。 【Qt学习】 OpenCV美图特效_qt图像处理_顾城沐心的博客-CSDN博客 问题1: 我发现是因为我使用的是MSVC2017 32位套件,改为MSVC2017 64位套件debug就好了。 感觉这是因为我选用的lib库也是64位的。 E:\opencv454\opencv…

使用STM32 再实现PWM小车两轮分别调速

关于PWM调速的原理,其实在之前89C52开发小车的时候也已经详细的描述过,所以主要的区别还是STM32和89C52的PWM实现区别。 关于STM32的PWM实现,是从CubeMX的配置开始的: CubeMX 1. 在上节的CubeMX项目基础上进行修改 2. 两路PWM分…

2023牛客暑期多校训练营2

题目顺序不分难度 KBox 状态dp,因为每个棋子只能移动到 i-1 到 i1的位置,所以直接用4个状态表示棋子在哪 f[i][0] 表示前i个位置中,i-1到i1都没有棋子 f[i][1] 表示前i个位置中,i-1有棋子 f[i][2] 表示前i个位置中&#xff0…

Autosar - PDUR简介与配置

文章目录 一、PDUR是什么二、不同报文类型的信号流ECUC(EcucPduCollection)三、时序图CanIfs之间的路由CanIf与Com之间的路由CanTp通道间的路由一、PDUR是什么 PDU Router(路由器)在本文将简称为PduR,在AUTOSAR的架构中,通信部份中很重要的一个模块就是PduR,它能将IPdu…

C++: day6

1 思维导图 2 顺序栈模板和顺序队列模板 #include <iostream>using namespace std;template <typename T> class My_stack { private:T *ptr; //指向堆区空间int top; //记录栈顶元素public://无参构造My_stack():ptr(new T[10]), top(-1){}//有参构造My_sta…

ROS-Moveit机械臂追踪二维码(四)

ROS-Moveit机械臂追踪二维码(四) 在仿真环境增加相机 <gazebo reference"camera_depth_frame"><sensor name"camera1" type"depth"><always_on>true</always_on><update_rate>20.0</update_rate><came…

多路选择器设计实现

文章目录 一、多路选择器二、二选一多路选择器三、四选一多路选择器设计 一、多路选择器 多路选择器是数据选择器的别称。在多路数据传送过程中&#xff0c;能够根据需要将其中任意一路选出来的电路&#xff0c;叫做数据选择器&#xff0c;也称多路选择器或多路开关。 二、二…

【从删库到跑路】MySQL数据库的索引(一)——索引的结构(BTree B+Tree Hash),语法等

&#x1f38a;专栏【MySQL】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出小吉的问题 文章目录 &#x1f354;概述&#x1f354;索引结构⭐B-Tree多路平衡查找树&#x1f3f3;️‍&a…

【分布式事务】CAP定理和Base理论

文章目录 1、事务的ACID原则2、分布式服务案例3、CAP定理4、Base理论5、分布式事务模型 1、事务的ACID原则 所有的事务都要满足ACID原则&#xff0c;在单体架构中&#xff0c;只有一个服务&#xff0c;这个服务访问一个数据库&#xff0c;场景简单。基于数据库本身的特性&…

React 组件使用

React 组件是一个 js 函数&#xff0c;函数可以添加 jsx 标记 当前页使用组件&#xff0c;基本使用 注意&#xff1a;组件的名称&#xff0c;第一个字母一定要大写&#xff0c;否则会报错 import { createRoot } from "react-dom/client"; import "./index.c…

深度学习(30)—— DeformableDETR(1)

深度学习&#xff08;30&#xff09;—— DeformableDETR&#xff08;1&#xff09; 原本想在一篇文章中就把理论和debug的过程都呈现&#xff0c;但是发现内容很多&#xff0c;所以就分开两篇&#xff0c;照常先记录理论学习过程&#xff0c;然后是实践过程。 注&#xff1a;…

Flutter学习—— Vscode创建项目

目录 一、Vscode创建项目 二、补充五种项目类型 Application: Module 模块开发&#xff0c; Package开发 Plugin 插件开发 Skeleton 骨架开发 一、Vscode创建项目 1.快捷键 CtrlShiftP 打开命令面板&#xff0c;选择新项目 2.选择需要开发的项目类型 Application 应用开…

勾股dev部署

1.克隆项目 项目的地址&#xff1a; https://gitee.com/gouguopen/dev?_fromgitee_search#-%E5%BC%80%E6%BA%90%E5%8A%A9%E5%8A%9B 可以采用git clone https://gitee.com/gouguopen/dev.git 或者使用下载压缩包的形式 2.进入项目的根目录 cd gougudev 3.下载php依赖 需要…

三种策略改进的沙猫群优化算法(MSCSO),与白鲸、蜣螂、麻雀等多种算法进行比较,MATLAB代码...

沙猫群优化算法(sand cat swarm optimiza⁃ tion,SCSO)是 2022年提出的元启发式优化算法&#xff0c;该算法灵感来源于沙猫的捕食行为&#xff0c;沙猫群会通过搜索阶段和捕食阶段获得食物。其中算法额外使用自适应的rG和R以达到搜索阶段和捕食阶段的无缝 切换。该算法具有寻优…

刷题日记09《图论基础》

图的存储结构 对于图结构而言&#xff0c;常见的存储结构主要有两种&#xff1a;邻接表和邻接矩阵&#xff1a; 邻接表很直观&#xff0c;我把每个节点 x 的邻居都存到一个列表里&#xff0c;然后把 x 和这个列表关联起来&#xff0c;这样就可以通过一个节点 x 找到它的所有相邻…