五、栈

  • 设计方式两种:1. 顺序栈:通过数组实现; 2. 链式栈:通过链表实现。
  • 栈的特点:LIFO 先进后出 / FILO 先进先出
  • 栈的操作:
  1. Push
  2. Top
  3. Pop
  4. IsEmpty

六、堆

栈、堆

栈、堆

  • 堆的分类:

栈、堆

注意和二叉搜索树的区别:大顶堆不分左右大小,只要根是最大的,任何一个儿子都比它小,任何一个孙子小于其父亲(也就是当前结点的儿子)更小于祖父(图里的根结点),就是大根堆。同理,小根堆就是任何一个父亲都小于其任何一个儿子。

  • 堆的插入操作(以大根堆为例):

栈、堆

假如此时插入95,那我们的插入做法是将其作为结点10(层序遍历从0开始,从左向右从大到小遍历):

栈、堆

但是我们的堆是大顶堆,所以现在的插入位置显然是不合适的,就需要向上渗透,即让其与其父亲进行交换:

栈、堆

此时95比81大,那继续让其与其父结点81进行交换,结果如下:
栈、堆

继续比较95比91大,继续交换:
栈、堆

最后完成插入:

栈、堆

总而言之:

  • 插入新节点  -->  向上渗透
  • 删除根节点  -->  向下渗透
  • 堆的插入操作(以大根堆为例):

假设现在要删除根结点95了,堆的初始状态如下图所示:

栈、堆

不管最后一个结点的值是多少,都先删除根结点并将最后一个节点放到根结点的位置:

栈、堆

栈、堆

但是此时的更改使得其不满足大根堆的属性,我们需要在根结点放一个大的值,那么就要将根结点向下渗透,去和左右两个儿子进行比较,找出其中较大的儿子,如图95即为所求,那么就将这两个结点进行交换:

栈、堆

然后再将当前的节点的左右儿子结点进行比较,然后找最大的,然后交换:

栈、堆

然后继续比较,然后交换,直到找到了合适的位置:

栈、堆

  • 堆的应用:
  1. 优先队列
  2. 排序

 

相关文章: