排序算法之堆排序
堆排序是基于完全二叉树的排序算法,即二叉树的除最后一层外每一层都达到容纳结点的最大值。最后一层从左至右依次排列。堆排序引入了另一种算法设计技巧,使用一种我们称为“堆”的数据结构来进行信息管理,不仅用在堆排序中,而且它也可以构造一种有效的优先队列。
堆是一个数组,它可以被看成一个类似于完全二叉树的数据结构。即如果我们认为数组下标为 “i” 的位置的元素为根节点,则它的左孩子为 “2 * i” 、右孩子为 “2 * i +1”.如果我们判断结点 ”i“ 的父节点是谁,则“ i / 2” 就是结点“i”的父结点。这里我们计算时采用整型并且默认向下取整。
堆可以分为两种,一种是“大顶堆”,即根节点必须保证大于左右孩子。另一种是“小顶堆”,即根节点必须保证小于左右孩子。
这里我们介绍的是堆排序,首先堆排序依照我的理解来看分三块:
1.堆排序的核心模块:即heapSort函数。
(1),构建初始堆
(2),倒序循环,从迭代元素=(数组长度 - 1)开始循环直到迭代元素=2执行完毕后跳出循环
(2.1)交换第一位 和 数组有效长度最后一位的元素
(2.2)从第一位 元素开始向下维护堆的性质
2.构建初始堆:即createMaxHeap
描述:从二叉树最后一个根节点向前遍历,维护出一个具备堆的性质的二叉树。
3.维护堆的性质:即maintainHeapSort
(1.)记录当前结点index的左右孩子的下标,如果左孩子的下标在有效范围内,并且左孩子大于当前结点index, 那么使用largest变量记录下左孩子的下标。否则用largest记录当前结点index的下标
(2.)如果右孩子的下标在有效范围内,并且右孩子大于当前结点index,那么使用largest变量记录下右孩子的下标。
(3.)如果 largest !=当前结点的下标,那么交换array[index]和array[largest]。并以largest所记录的孩子的下标为参数调用maintainHeapSort
图解:
源代码:
/**
* 堆排序入口,需要传入一个长度大于等于2的数组
* 如果小于2就别排序了,没啥用也
* @pa