堆
堆是用数组实现的二叉树
堆中所有结点的值必须大于或等于(或小于或等于)其孩子结点的值;
堆还有另一个性质,就是当 h > 0 时,所有叶子结点都处于第 h 或 h - 1 层(其中 h 为树的高度,完全二叉树),也就是说,堆应该是一颗完全二叉树;
堆的应用,这是一种特别适合用来找第k小/大的特殊的数据结构,并且在Java中有直接的实现
-
插入
往最后一个位置插入,让后使它上浮,基本思想是从最后一个位置开始,通过上浮操作不断调整位置,直到满足父节点的优先级必定大于子节点这个条件。
上浮是往二叉堆添加元素用到的操作,它其实是不断的调整k的位置为父元素的位置直到满足条件为止。 -
删除
让根节点元素和最后一个节点进行交换,然后让现在的根元素下沉
删除指定位置的元素,其基本思想是从指定位置开始,把最后一个元素放到被删除元素的位置,通过下沉或者上浮操作,使得堆满足父元素优先级大于子元素的条件。
下沉是删除时用到的操作。它是把最后一个元素放到被删除元素的位置,然后重新调整使得堆满足条件的过程。
- 当被删除元素的位置位于最后一个元素的父元素的位置后面时,可以直接把最后一个元素插入到被删除元素的位置;然后再进行上浮操作。
- 否则,需要执行下沉操作。
- 堆排序:开一个新的数组,每次取堆顶元素放进去,然后弹掉堆顶(时间复杂度是O(nlogn))
栈
栈的应用——递归
在高级语言中,调用自己和其它函数没有本质的不同。我们把一个直接用自己或通过一系列的调用语句间接地调用自己的函数,称作递归函数。每个递归函数必须至少有一个条件,满足时递归不再执行,即不再引用自身而是返回值退出。
递归和迭代的区别是:迭代使用的是循环结构,递归使用的是选择结构。 递归能使程序的结构更清晰、更简洁、更容易让人理解,从而减少读懂代码的时间。但是大量的递归调用会建立函数的副本,会耗费大量的时间和内存。迭代则不需要反复调用函数和占用额外的内存。因此我们应该视不同情况选择不同的代码实现方式。
在前行阶段,对于每一层递归,函数的局部变量、参数值以及返回地址都被压入栈中。在退回阶段,