python 堆与栈

【一】堆与栈

【 1 】简介

        栈(stack),有些地方称为堆栈,是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一端(称为栈顶端指标,英语:top)进行加入数据(英语:push)和输出数据(英语:pop)的运算。没有了位置概念,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素,确定了一种默认的访问顺序。

由于栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 。。

4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放。

5、程序代码区—存放函数体的二进制代码。

【 2 】堆与栈的区别

        堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:
(1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;

(2)空间大小不同。每个进程拥有的栈大小要远远小于堆大小。理论上,进程可申请的堆大小为虚拟内存大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;

(3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。

(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有 2 种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca()函数分配,但是栈的动态分配和堆是不同的,它的动态分配是由操作系统进行释放,无需我们手工实现。

(5)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。显然,堆的效率比栈要低得多。

(6)存放内容不同。栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等。当主函数调用另外一个函数的时候,要对当前函数执行断点进行保存,需要使用栈来实现,首先入栈的是主函数下一条语句的地址,即扩展指针寄存器的内容(EIP),然后是当前栈帧的底部地址,即扩展基址指针寄存器内容(EBP),再然后是被调函数的实参等,一般情况下是按照从右向左的顺序入栈,之后是被调函数的局部变量,注意静态变量是存放在数据段或者BSS段,是不入栈的。出栈的顺序正好相反,最终栈顶指向主函数下一条语句的地址,主程序又从该地址开始执行。堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的。

从以上可以看到,堆和栈相比,由于大量malloc()/free()或new/delete的使用,容易造成大量的内存碎片,并且可能引发用户态和核心态的切换,效率较低。栈相比于堆,在程序中应用较为广泛,最常见的是函数的调用过程由栈来实现,函数返回地址、EBP、实参和局部变量都采用栈的方式存放。虽然栈有众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,主要还是用堆。

无论是堆还是栈,在内存使用时都要防止非法越界,越界导致的非法内存访问可能会摧毁程序的堆、栈数据,轻则导致程序运行处于不确定状态,获取不到预期结果,重则导致程序异常崩溃,这些都是我们编程时与内存打交道时应该注意的问题。

【 二 】什么是堆和栈,它们在哪儿?

    • 栈是一种后进先出(LIFO)的数据结构,类似于一摞盘子或者书籍,你只能在顶部放置新的盘子或者拿走顶部的盘子。
    • 在编程语言中,栈通常用于存储函数调用的信息(局部变量、参数、返回地址等)。每次函数调用时,相关的信息被压入栈中;当函数返回时,这些信息被弹出。
    • 栈是一块连续的内存区域,其大小在程序启动时就被确定。

    • 堆是一种用于动态分配内存的数据结构,它的内存空间可以动态地增长或缩小。
    • 在编程语言中,堆通常用于存储动态分配的数据,比如对象、数组等。由于堆的动态性质,数据的存储位置和大小可以在运行时动态确定。
    • 堆并不需要连续的内存区域,它的分配和释放由程序员显式地控制。

        总的来说,栈和堆是计算机内存中两种重要的数据结构,它们分别用于不同的目的和场景。栈主要用于存储函数调用信息,而堆主要用于动态分配内存以存储复杂的数据结构。在编程中,了解栈和堆的特点对于有效地管理内存和理解程序的执行过程非常重要。

【 三 】栈结构实现

使用

        栈可以用顺序表实现,也可以用链表实现。

栈的操作

  1. Stack() 创建一个新的空栈
  2. push(item) 添加一个新的元素item到栈顶
  3. pop() 弹出栈顶元素
  4. peek() 返回栈顶元素
  5. is_empty() 判断栈是否为空
  6. size() 返回栈的元素个数
1 class Stack(object):2     """栈"""3     def __init__(self):4          self.items = []5 6     def is_empty(self):7         """判断是否为空"""8         return self.items == []9 
10     def push(self, item):
11         """加入元素"""
12         self.items.append(item)
13 
14     def pop(self):
15         """弹出元素"""
16         return self.items.pop()
17 
18     def peek(self):
19         """返回栈顶元素"""
20         return self.items[len(self.items)-1]
21 
22     def size(self):
23         """返回栈的大小"""
24         return len(self.items)
25 if __name__ == "__main__":
26     stack = Stack()
27     stack.push("hello")
28     stack.push("world")
29     stack.push("itcast")
30     print stack.size()
31     print stack.peek()
32     print stack.pop()
33     print stack.pop()
34     print stack.pop()

利用python中列表的方法实现数据结构中堆栈的“后进先出”的性质

列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。

 用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如:

>>> stack = [1, 2, 3]
>>> stack.append(4)
>>> stack.append(5)
>>> stack
[1, 2, 3, 4, 5]
>>> stack.pop()
5
>>> stack
[1, 2, 3, 4]
>>> stack.pop()
4
>>> stack.pop()
3
>>> stack
[1, 2]

【 四 】堆结构实现

使用

        在 Python 中,可以使用 heapq 模块来实现堆结构。heapq 提供了一些函数和工具,可以方便地进行堆操作。

以下是使用 heapq 模块实现最小堆的示例代码:

import heapqclass MinHeap:def __init__(self):self.heap = []def insert(self, item):heapq.heappush(self.heap, item)def extract_min(self):if self.is_empty():return Nonereturn heapq.heappop(self.heap)def is_empty(self):return len(self.heap) == 0def get_min(self):if self.is_empty():return Nonereturn self.heap[0]

在这个示例中,我们定义了一个 MinHeap 类,并使用 heapq 模块提供的函数来实现堆操作:

  1. __init__(): 初始化一个空堆。
  2. insert(item): 向堆中插入元素。
  3. extract_min(): 弹出并返回堆中的最小元素。
  4. is_empty(): 判断堆是否为空。
  5. get_min(): 返回堆中的最小元素,但不弹出。

可以使用以下代码测试上述实现的最小堆:

h = MinHeap()
print(h.is_empty())  # Trueh.insert(5)
h.insert(3)
h.insert(8)
h.insert(2)
print(h.extract_min())  # 2print(h.is_empty())  # False
print(h.extract_min())  # 3
print(h.extract_min())  # 5
print(h.extract_min())  # 8
print(h.is_empty())  # True

  heapq 模块内部使用了优化的堆操作算法,可以高效地进行堆操作。你可以根据需要在代码中添加其他操作,比如获取堆顶元素或者删除指定元素,以满足具体的需求。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.qml-3D入门讲解介绍

本章我们来学习QML 3D教程,QML 3D能够支持windows linux等多平台跨平台并且显示效果大部分一致,非常方便,学习的qt版本最低为qt6.5。 要使用qml 3D类,需要导入QtQuick3D模块。 这是使用空间渲染器和场景图的 QML 前端。目前&…

(六)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)

一、无人机模型简介: 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献: [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、Tiki-taka算法(TTA&#xf…

360公司-2019校招笔试-Windows开发工程师客观题合集解析

360公司-2019校招笔试-Windows开发工程师客观题合集 API无法实现进程间数据的相互传递是PostMessage2.以下代码执行后,it的数据为(异常) std::list<int> temp; std::list<int>::iterator it = temp.begin(); it = --it; 3.API在失败时的返回值跟其他不一样是 …

【EI会议征稿】第五届人工智能、网络与信息技术国际学术会议(AINIT 2024)

第五届人工智能、网络与信息技术国际学术会议&#xff08;AINIT 2024&#xff09; 第五届人工智能、网络与信息技术国际学术会议&#xff08;AINIT 2024&#xff09;将于2024年3月22-24日在中国南京举行。本届会议将主要关注人工智能、网络与信息技术面临的新的挑战问题和研究…

服务器主机安全用什么防护软件好?

一直以来服务器是许多企业、机构和个人进行关键任务操作的基础&#xff0c;而保护服务器主机安全是一项重要的任务&#xff0c;其中使用高防ip进行保护是有效且实用的方法&#xff0c;因为服务器主机安全受到危害的影响是多方面的&#xff0c;这边对于这方面也是进行了一定的了…

MagicPipe3D地下管网三维建模数据规格

经纬管网建模系统MagicPipe3D&#xff08;www.magic3d.net&#xff09;本地离线参数化构建三维地下管网&#xff08;含管道、接头、附属物等&#xff09;模型&#xff0c;输出标准3DTiles、Obj等格式&#xff0c;支持Cesium、Unreal、Unity等引擎可视化查询。MagicPipe3D三维建…

Linux last命令教程:如何查看用户的登录和注销历史(附案例详解和注意事项)

Linux last命令介绍 last命令在Linux中用于显示自文件/var/log/wtmp创建以来所有用户的登录和注销列表。可以给出一个或多个用户名作为参数&#xff0c;以显示他们的登录&#xff08;和注销&#xff09;时间和主机名。 Linux last命令适用的Linux版本 last命令在大多数Linux…

数据结构——希尔排序(详解)

呀哈喽&#xff0c;我是结衣 不知不觉&#xff0c;我们的数据结构之路已经来到了&#xff0c;排序这个新的领域&#xff0c;虽然你会说我们还学过冒泡排序。但是冒泡排序的性能不高&#xff0c;今天我们要学习的希尔排序可就比冒泡快的多了。 希尔排序 希尔排序的前身是插入排…

CETN01 - How to Use Cloud Classroom

文章目录 I. Introduction to Cloud ClassroomII. How to Use Cloud Classroom1. Publish Resources2. Conduct Activities3. Class Teaching Reports4. View Experience Values5. Performance in Cloud Classroom I. Introduction to Cloud Classroom “Cloud Classroom” is …

LeNet对MNIST 数据集中的图像进行分类--keras实现

我们将训练一个卷积神经网络来对 MNIST 数据库中的图像进行分类&#xff0c;可以与前面所提到的CNN实现对比CNN对 MNIST 数据库中的图像进行分类-CSDN博客 加载 MNIST 数据库 MNIST 是机器学习领域最著名的数据集之一。 它有 70,000 张手写数字图像 - 下载非常简单 - 图像尺…

QT 中 QDateTime::currentDateTime() 输出格式备查

基础 QDateTime::currentDateTime() //当前的日期和时间。 QDateTime::toString() //以特定的格式输出时间&#xff0c;格式 yyyy: 年份&#xff08;4位数&#xff09; MM: 月份&#xff08;两位数&#xff0c;07表示七月&#xff09; dd: 日期&#xff08;两位数&#xff0c…

【unity3D】unity中如何查找和获取游戏物体

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity中游戏物体的查找与获取 这里写自定义目录标题 获取当前物体的基本属性查找其它物体- 通过名称查找其它物体- 通过标签查找- 通过类…

计算机网络入侵检测技术研究

摘 要 随着网络技术的发展&#xff0c;全球信息化的步伐越来越快&#xff0c;网络信息系统己成为一个单位、一个部门、一个行业&#xff0c;甚至成为一个关乎国家国计民生的基础设施&#xff0c;团此&#xff0c;网络安全就成为国防安全的重要组成部分&#xff0c;入侵检测技术…

C++系统思维导图

自己在复盘C的时候做了 一些笔记&#xff0c;用思维导图形式记录下来的一些概念&#xff0c;多线程的内容较少&#xff0c;主要是派生和继承&#xff0c;以及虚函数和多态内容多一些&#xff0c;其他也有一些零碎的小知识点&#xff0c;和大家分享一下。有任何问题请留言。原图…

生鲜蔬果展示预约小程序作用是什么

线下生鲜蔬果店非常多&#xff0c;对商家来说主要以同城生意为主&#xff0c;而在互联网电商的发展下&#xff0c;更多的商家会选择搭建私域商城进行多渠道的销售卖货和拓展&#xff0c;当然除了直接卖货外&#xff0c;还有产品纯展示或预约订购等需求。 但无论哪种模式&#…

ubuntu离线安装包下载和安装

一、确认本机ubuntu的发行版本 方法1: rootac810:/home/ac810/alex# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal 方法2: rootac810:/home/ac810/alex# cat /…

uniapp小程序分包页面引入wxcomponents(vue.config.js、copy-webpack-plugin)

实例&#xff1a;小程序添加一个源生小程序插件&#xff0c;按照uniapp官方的说明&#xff0c;要放在wxcomponents。后来发现小程序超2m上传不了。 正常的编译情况 会被编译到主包下 思路&#xff1a;把wxcomponents给编译到分包sub_package下 用uniapp的vue.config.js自定义…

电脑如何录音?适合初学者的详细教程

“电脑怎么录音呀&#xff1f;参加了一个学校举办的短视频大赛&#xff0c;视频拍摄都很顺利&#xff0c;音乐却出了问题&#xff0c;朋友说可以用电脑录制一段音乐应付一下&#xff0c;可是我不会操作&#xff0c;有哪位大佬教教我&#xff01;” 声音是一种强大的媒介&#…

智能电表需要安装电池吗?

智能电表是一种新型的电力测量设备&#xff0c;它使用先进的技术和功能来监控、记录和报告能源消耗情况。对于智能电表是否需要安装电池这个问题&#xff0c;答案是有可能需要&#xff0c;但并不是所有智能电表都需要安装电池。 首先&#xff0c;我们需要了解智能电表是如何工作…

从0开始使用Maven

文章目录 一.Maven的介绍即相关概念1.为什么使用Maven/Maven的作用2.Maven的坐标 二.Maven的安装三.IDEA编译器配置Maven环境1.在IDEA的单个工程中配置Maven环境2.方式2&#xff1a;配置Maven全局参数 四.IDEA编译器创建Maven项目五.IDEA中的Maven项目结构六.IDEA编译器导入Mav…