编程思想 - 堆排序

堆是一颗完全二叉树。

简而言之,一个二叉树是饱满的---即二叉树都满了,即使没有饱满,那么上一层都是饱满,最后一层叶子节点从左向右排列。


但是堆相对于完全二叉树有了自己的特点,堆分成最大堆及最小堆,

对于最大堆有:

1、根节点(堆顶)的关键字是最大(至少要大于或等于)的;

2、父亲节点必然比左右子节点都要大(至少等于)--左右节点之间没有大小之分,但是都比父亲节点少。


对于最小堆,性质类似:

1、根节点(堆顶)比所有子节点都小或等于;

2、父亲节点比左右子节点都要小或等于。

堆的存储

一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。


堆操作

最大堆的插入 --- 节点上浮

由于需要维持完全二叉树的形态,需要先将要插入的结点x放在最底层的最右边,插入后满 足完全二叉树的特点; 
  然后把x依次向上调整到合适位置满足堆的性质,例如下图中插入80,先将80放在最后,然后两次上浮到合适位置. 
  时间:O(logn)。  “结点上浮” 



最大堆的删除  --- 节点下沉 

操作原理是:当删除节点的数值时,原来的位置就会出现一个孔,填充这个孔的方法就是, 
把最后的叶子的值赋给该孔并下调到合适位置,最后把该叶子删除。 节点下沉



堆的初始化

调整法:

序列对应一个完全二叉树;从最后一个分支结点(n div 2)开始,到根(1)为止,依次对每个分支结点进行调整(下沉),
以便形成以每个分支结点为根的堆,当最后对树根结点进行调整后,整个树就变成了一个堆。 
  时间:O(n) 

对如图的序列,要使其成为堆,我们从最后一个分支结点(10/2),其值为72开始,依次对每个分支节点53,18,36 45进行调整(下沉). 








参照:

https://blog.csdn.net/morewindows/article/details/6709644/

https://blog.csdn.net/abcd1f2/article/details/47260095


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页