堆排序
高能预警:堆排序是八大排序算法中的最后一个算法,排序过程不难懂,但代码实现有点难度,建议视频+本文的形式学习。
堆排序需要的知识:二叉树基础+顺序存储二叉树+排序意识
堆排序过程:先看下图
通过顺序存储二叉树,将一个无序数组转变为一个完全二叉树(这个树并不真实存在,数据仍然保存在数组中,而非树中。我们是用树的逻辑来解释整个排序过程)。
整个过程分为3个阶段:【1】创建堆(升序创建大顶堆(所有子树都满足父节点大于两个子节点),降序创建小顶堆(所有子树都满足父节点小于两个子节点)),【2】将根节点元素与树的最后一个元素对调位置(对调后最后一个元素成为最大值,将从树中脱离,不再参与操作),【3】将剩余元素再次创建堆
以上过程直到所有元素脱离树结构为止。下面对每一个过程细讲一下(以升序为例):
【1】最开始,先以从右向左,从下向上的顺序,从最后一个非叶子节点(array.length/2-1)开始,将其与其左右子节点进行比较,将大的与父节点位置对调。
重复以上操作,直到根节点的子树也被排完。形成大顶堆为止。
【2】完成创建大顶堆后,将根节点元素与最后头的结点元素进行对调,对调完成后,最后的结点脱离树。
【3】将剩余的结点,从根节点开始,再次进行大顶堆的创建。不断调换,脱离,重建直到只剩根节点,排序完成。
package cn.dataStructureAndAlgorithm.demo.sort;
import java.util.Arrays;
public class 堆排序_heapSort {
public static void main(String[] args) {
int data[]=new int[]{10,6,8,5,9};
heapSort(data);
System.out.println(Arrays.toString(data));
}
public static void heapSort(int data[]){
int temp;//对调操作的中介变量
//创建大顶堆
//data.length/2-1可以找到最后一个父节点,不断找到父节点,并将创建大顶堆
for (int i=data.length/2-1;i>=0;i--){
adjustHeap(data,i,data.length);
}
//对调操作,脱落操作,重建操作
for (int i=data.length-1;i>0;i--){
//对调
temp=data[i];
data[i]=data[0];
data[0]=temp;
adjustHeap(data,0,i);//脱落,从根节点重建
}
}
/**
*对传入的数组,根据父节点索引,长度,进行大顶堆的创建
* @param data 待创建大顶堆的数组
* @param father 父节点索引
* @param length 数组长度
*/
public static void adjustHeap(int data[],int father,int length){
int tempFather=data[father];//暂存父节点的值
//对父节点其所在子树进行大顶堆的建立
for (int i=father*2+1;i<length;i=i*2+1){//i代表左子节点,但i不能下标过界;一轮完成之后,对子节点所在的子树再重复操作
if (i+1<length && data[i]<data[i+1]){//i+1代表右子节点,但i+1不能下标越界,但符合条件时,意味着右节点更大
i++;//i指向右子节点
}
//此时i指向的都是最大子节点,接下来将最大子节点与父节点进行判断
if (data[i]>tempFather){//当比父节点更大时
data[father]=data[i];//最大节点放到父节点上
father=i;//重置父节点指向为之前移动的最大节点,对子节点所在的子树再重复操作
}else {
break;//当没有比父节点大时,说明后续的树已经排好了,停止循环
}
}
//循环完成后,father指向需要与父节点替换的最大子节点上,所以要进行替换
data[father]=tempFather;
}
}
[5, 6, 8, 9, 10]
堆排序速度测试:以8000000个【0~8000000】的随机整数为数组,进行速度测试(数据以我电脑为准,本次测速与希尔移位式,快排,归并,基排比较,并将数据量*1000)
希尔移位式式耗时:2s 快速排序耗时:907ms 归并排序耗时:1s 基数排序耗时:487ms 堆排序耗时:1s
堆排序具有既高效率又节省空间的特点。最大的也是唯一的缺点就是——堆的维护问题。每当数据变动时,都要对堆重新维护,使之形成大顶堆或小顶堆。
至此,恭喜你获得【排序大师】称号
有关树结构的其他内容,见下各链接
【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)