算法思路堆排序(heap sort)是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序。
输入数组并建立小顶堆,此时最小元素位于堆顶。
不断执行出堆操作,依次记录出堆元素,即可得到从小到大排序的序列。
以上方法虽然可行,但需要借助一个额外数组来保存弹出的元素,比较浪费空间。在实际中,我们通常使用一种更加优雅的实现方式。
算法流程设数组的长度为 n ,堆排序的流程如下图所示。
输入数组并建立大顶堆。完成后,最大元素位于堆顶。
将堆顶元素(第一个元素)与堆底元素(最后一个元素)交换。完成交换后,堆的长度减 1 ,已排序元素数量加 1 。
从堆顶元素开始,从顶到底执行堆化操作(sift down)。完成堆化后,堆的性质得到修复。
循环执行第 2. 步和第 3. 步。循环 n−1 轮后,即可完成数组排序。
算法特性
时间复杂度为 O(nlogn)、非自适应排序:建堆操作使用 O(n) 时间。从堆中提取最大元素的时间复杂度为 O(logn) ,共循环 n−1 轮。
空间复杂度为 O(1)、原地排序:几个指针变量使用 O(1) 空间 ...
算法思路归并排序(merge sort)是一种基于分治策略的排序算法,包含下图所示的“划分”和“合并”阶段。1.划分阶段:通过递归不断地将数组从中点处分开,将长数组的排序问题转换为短数组的排序问题。2.合并阶段:当子数组长度为 1 时终止划分,开始合并,持续地将左右两个较短的有序数组合并为一个较长的有序数组,直至结束。
“划分阶段”从顶至底递归地将数组从中点切分为两个子数组。
计算数组中点 mid ,递归划分左子数组(区间 [left, mid] )和右子数组(区间 [mid + 1, right] )。
递归执行步骤 1. ,直至子数组区间长度为 1 时终止。
“合并阶段”从底至顶地将左子数组和右子数组合并为一个有序数组。需要注意的是,从长度为 1 的子数组开始合并,合并阶段中的每个子数组都是有序的。
归并排序与二叉树后序遍历的递归顺序是一致的。
后序遍历:先递归左子树,再递归右子树,最后处理根节点。
归并排序:先递归左子数组,再递归右子数组,最后处理合并。
动画演示
算法特性
时间复杂度为 O(nlogn)、非自适应排序:划分产生高度为 logn 的递归树,每层合并的总 ...
算法思路通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
1、首先设定一个分界值,通过该分界值将数组分成左右两部分。
2、将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
3、然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
4、重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
概括来说为 挖坑填数 + 分治法
动画展示
算法性能时间复杂度理想情况如果足够理想,那我们期望每次都把数组都分成平均的两个部分,如果按照这样的理想情况分下去,我们最终能 ...