堆与栈介绍与区别

168 阅读4分钟

作为一个程序员,你很可能遇到过 "堆 "和 "栈 "这两个术语。对初学者来说,交替使用这两个术语是一种普遍的做法,而且是错误的。

虽然数据结构课程的学生和有经验的程序员会很容易区分这两个数据结构,但对其他人来说,它们可能是一样的。

程序员需要区分这两者,并在实际编程情况下适当地使用它们。面试官往往热衷于给申请人一个场景,然后询问最合适的数据结构。

请继续阅读,我们将详细了解堆、栈、它们的区别和相关应用。

什么是堆?

对于程序员来说,堆通常是一种特殊的树状数据结构,通常被称为 "优先队列"。作为一个完全平衡的二叉树结构(回顾一下,一个完整的二叉树的所有层次都被填满,除了最后一层)并遵循一个堆属性的堆被称为二叉堆。

堆属性以一种将最大值或最小值置于根部的方式来构造树。

相关的。免费学习代码的最佳途径

在最大堆中,父节点的值大于子节点的值,树的根部包含最大值。另外,Min Heap的结构是以最小值为根,每个子节点的值都大于其父节点的值。对于二叉树中的每个节点,堆的属性必须是递归的真。

堆一般通过线性数组实现,数组的第一个元素**(Arr[0])代表根。对于一个特定的节点i**,你可以在Arr[ (2*i) + 1 ]Arr[ (2*i) + 2 ]检索到子节点,同样,父节点位于Arr[ (i-1)/2 ] 索引。大多数语言,如Java和C++,都含有为用户提供现成的最小和最大堆的库。

什么是堆?

堆栈是最早教给学生的数据结构之一,它们不应该被忽视。堆栈是一种数据结构,其行为类似于现实生活中的任何堆栈(卡片、盘子等)。堆栈只允许在一端进行操作,因此,它们具有后进先出(Last-In-First-Out)的特性。与此相反,队列具有FIFO(先进先出)特性,允许在两端进行操作。

典型的堆栈操作包括推(将数据插入到堆栈的顶部)和弹(移除最顶部的数据元素)。你可以通过指针、数组,甚至是链接列表来实现堆栈,这取决于你的要求。C++、C#和Java都包含已经实现了堆栈的库,所以你可以随时使用它们。

堆与栈

如果你读到这里,你已经对堆栈和堆之间的区别有了很好的了解。堆是线性的,具有后进先出的特性,而堆有一个树状结构,遵循堆的特性。它们都有不同的应用,我们将在下一节讨论。

就渐进时间复杂度分析而言,你可以在O(n)中建立一个二进制堆,在O(1)中提取最小或最大的值。插入和删除可以在O(log N)时间内实现。相比之下,在堆中插入和删除需要O(1)时间。

典型应用

由于上面讨论的原因,堆在用作优先级队列时是非常有效的。图算法,如Prim的最小生成树和Dijkstra的最短路径,通常利用堆作为优先队列。堆的另一个重要应用是在仅仅O(N logN)的时间内对一个数组进行有效排序;这种排序技术被称为 "堆排序"。

相关的。插入式排序算法简介

栈,也有各种关键的应用,如内存管理和表达式评估。如果你面临一个回溯编码的问题,使用堆栈来拯救这一天也许是个好主意。

优先考虑数据结构

每个成功的程序员都会告诉你熟练掌握数据结构的重要性。在需要的时候,尝试理解并熟练使用不同的数据结构是一个好主意,因为这对每个程序员来说都是一个重要的概念。