排序算法之---堆排序(很重要的一个结构,新手入门必备)
先来简单的介绍一下堆结构:
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它是不稳定排序。首先简单了解下堆结构。
堆是具有以下性质的完全二叉树:
每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;
每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
如下图:
大根堆和小根堆在数组中的特点如下:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] (i是指父节点,2i+1是子节点)
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
下面就来介绍一下堆排序的基本思想和步骤:
堆排序的基本思想是:将待排序的序列构造成一个大顶堆(1),此时,整个序列最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆(2),这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了(3)
(1)将待排序的序列构造成一个大根堆:
将数组一个一个插入大根堆中:当插入的元素比起父节点大的时候,与父节点交换,并且将父节点的索引赋值给子节点,不断地 往上递归上去比较。
举个粟子:
当插入9的时候,比较完发现9还比交换后的父节点大,那就还要继续交换了。
(2)构成大根堆之后,此时整个序列最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆。
54~58这几行表示的是:这个时候就要将较大的子节点与父节点进行比较了,如果子节点更大的话,那就交换父节点和子节点
59~60行这里则表示,当子节点比其父节点还大的时候,交换它们两个的位置,同时,将index指针往下传,继续判断是否有比父节点还大的子节点。
参考:https://www.cnblogs.com/chengxiao/p/6129630.html,这篇博文写的很清晰,只是不同的是,大根堆的形成不是很相同。可以参考,很详细。