变治法的关键在于巧妙转换问题,不走常规路,如化未知为已知。堆排序的巧妙之处在于转换了数据结构。对一个普通的无序数组排序,我们知道有合并、快排等方法。但如果我们改变数组的结构,将其变成一个完全二叉树,就可以采取堆排序的方法。后面可以发现,采用堆排序的方法在实现找到、删去最大值、添加元素等操作上效率很高。因此,堆排序是变治法的一个成功实现。
堆排序的数据结构基础是“堆”,而堆的本质结构是一个满足特定要求的完全二叉树。
其特征为:1. 树的每一层都是满的,只有最后一层右侧的元素可能缺位(最后一层从左向右填充)2. 对于最大堆,父节点一定大于子女节点的键值,不过同一层的节点之间没有大小关系。(对于最小堆则相反)
要对给定无序数组排序,首先要将其转成一个完全二叉树的结构。通过键值之间的特定关系可以进行这一转换,其输出形式仍然可以为一个数组,只不过此时数组不同位置上的元素有了特定关系(父节点-子女节点)。
第二步是把这个完全二叉树转成一个最大堆的结构,即“建堆”的过程。
然后,删除根节点,删除之后维护其最大堆性质,再删除新的根节点,这样循环n次直到所有根节点删除完。把根节点按照其被删除的顺序记录下来即完成了对数组的从大到小排序。
整个过程中涉及两个重要操作&