在面试的时候我们经常被问到堆和栈相关的问题,悲催的是还傻傻分不清面试官要问的是哪个堆栈。
是的,堆和栈有两层含义,分别对应如下两个方面:
数据结构中的堆和栈、以及队列
1. 堆
官方定义如下:n个元素的序列{k1, k2, … kn},当且仅当满足以下关系时称之为堆:
堆其实就是利用完全二叉树的结构来维护的一维数组
如果所有的子节点都小于其父节点,这样的堆称为大顶堆;相反称为小顶堆
堆数据结构的介绍就这么些了,那它有啥用呢?我们发现如果一直取根节点,得到的序列就是一个有序序列,感觉这样的数据结构天生就是为排序准备的呀。
2. 栈
栈是一种先进后出的数据结构,官方定义为:限定仅在表尾进行插入或删除操作的线性表,表尾称为栈顶,表头为栈底。
说白了,栈在数据结构里边可以看成是一端封死了的容器。就像米缸一样的,先倒进去的米最后才能倒出来。
别看这么简单的一个数据结构,其用途可不可小觑,从普通代码开发到编译器再到内核都有其身影,最常见如编译器中的括号匹配,内核中的程序现场保存等。、
3. 队列
队列跟栈有点类似,只是它是一个先进先出的数据结构。只运行在表的一端插入,另一端删除,插入的一方叫队尾,删除的一方叫队头。
操作系统中的堆栈
在操作系统中的堆栈是一个特殊的存储区,栈一般是由操作系统控制分配回收,用在如局部变量,函数调用存储等地方,其大小是固定的(比如有些系统为2M),所以如果要求分配的空间大于了栈的大小,将出现栈溢出。
堆是由用户(码农)控制分配和回收,此处的控制是指显式调用一个系统函数,如malloc,free等,从系统中分配一个所需大小的空间出来。其在系统中的存储方式依据系统的不同而不同,在Linux系统中,堆可以理解成一个链表数组,该链表数组中存放的是内存空间地址,如下这样的设计:
当需要分配时,系统将从对应大小的列表中摘一个下来分给用户,如果分配空间过多,会将多余的空间挂接到对应的列表下。