我之前一直有这样的疑问:
为什么我们在使用数组中堆排序的时候一般都采用sink即下沉操作而非swim操作呢?
一经查阅相关知识,了解到:swim操作的时间复杂度(将一个数组排序的时间复杂度)为
O(N*logN),而sink操作的时间复杂度(将一个数组排序的时间复杂度)为O(N)。
那么问题来了,为什么同为堆排序的手段,二者的时间复杂度却相差这么大呢?
我们来逐个分析:
swim操作:
我们知道,在一个结点数大小为N的二叉树中,其二叉树的高度为log(N+1),于是
我们有一种堆排序的方法就是从左至右遍历数组,并用一个size指针(索引)维护已经
排好序的二叉树(这里的排好序是指大二叉树的一部分在size大小的小数组中是排好序的二叉树)
然后我们每次将size指针的后一个元素加入size的小数组中,并扩大size的规模加1,这样定型
去分析每个元素,我们不难发现,一个元素去往它应该去的地方需要两个操作,一是比较,
二是交换;因为一个二叉树的高度最高为log(N+1),我们又要将N个元素全部归位,故
swim操作的时间复杂度就是NlogN了;
sink操作:
sink操作的思想就是当一个结点(叶结点除外)的两个子堆都为有序的话,那么在这个结点
上再次调用sink函数就能把以这个结点为父节点的二叉树变成一个堆