update readme
This commit is contained in:
+5
-28
@@ -246,40 +246,17 @@ public void merge(int[] arr,int low,int mid,int high,int[] tmp){
|
||||
|
||||
利用堆这种数据结构设计的一种排序算法
|
||||
|
||||
先来了解下 `堆` 结构
|
||||
|
||||
堆分小根堆和大根堆
|
||||
|
||||
堆: 任一节点小于(或大于)其所有的孩子节点,如果是大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。
|
||||
|
||||
堆也被称为`优先队列`
|
||||
堆总是一颗完全树
|
||||
|
||||
`堆用数组来存储`,i节点的父节点就是(i-1)/2,左右子节点小标是 2i+1,2i+2。
|
||||
|
||||
堆的操作有:
|
||||
|
||||
建堆
|
||||
插入:都是插入到数组最后,然后再调整满足堆次序
|
||||
删除:删除总是发生在 A[0]处,也就是只删除根节点
|
||||
|
||||
这样难怪`堆`被称为 `优先队列`。插入和删除分别在 数组尾部和头部,只是需要再次调整以满足堆次序。
|
||||
|
||||
`堆`的应用场景有:
|
||||
优先队列 如iOS中的NSOperationQueue 就是维护一个优先队列
|
||||
堆排序
|
||||
|
||||
|
||||
[堆结构参考这里](../4%20Tree/8-堆/堆.md)
|
||||
|
||||
我们来看看如何使用`堆` 来做排序?
|
||||
|
||||
1.将待排序数列看做一颗完全二叉树的存储结构
|
||||
2.`堆化数组`,结束后,根a[0]变成了最小的值(小根堆)
|
||||
3.取a[0]值,然后对`堆`做删除操作,此时,`堆`会重新 `堆化数组`,a[0]又是下一个最小的值。
|
||||
1. 将待排序数列看做一颗完全二叉树的存储结构
|
||||
2. `堆化数组`,结束后,根a[0]变成了最小的值(小根堆)
|
||||
3. 取a[0]值,然后对`堆`做删除操作,此时,`堆`会重新 `堆化数组`,a[0]又是下一个最小的值。
|
||||
删除操作通常是先把数组最后的元素提到a[0]位置,然后从根节点开始进行一次从上向下的调整;调整时,先从左右孩子中找最小的交换。如果父节点比每个节点都小就不用调整。(因此,在`堆排序`是可以直接让 a[0]和数组最后一个元素互换,但要先保存好a[0],或者a[n-1],这样导致了使用`堆排序`时,递增排序使用大根堆,递减排序使用小根堆。)
|
||||
4. 循环3,就可以按从小到大的顺序取出所有数组元素。
|
||||
|
||||
堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大树只需要O(1)时间复杂度
|
||||
堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大数只需要O(1)时间复杂度
|
||||
|
||||
|
||||
void heap_sort(int *a, int length){
|
||||
|
||||
Reference in New Issue
Block a user