Java堆排序

Posted 木木林Violet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java堆排序相关的知识,希望对你有一定的参考价值。

目录

堆排序,顾名思义,就是要用到堆的知识。其基本的原理也就是选择排序,知识不再使用遍历的方式查找无序区间的最大数,而是用堆来来选择无序区间中的最大值。但是需要注意的是,排升序需要用到最大堆,排降序需要用到最小堆。

排序流程图

排序思想

在讲解堆排序思想前,需要先知道一些关于堆排序的知识:
1.堆在逻辑上事一颗完全二叉树。
2.堆在物理上是保存在数组中(按照层序遍历顺序保存)。
3.最大堆:每一个节点的值都大于或等于其两个子节点的值。
4.最大堆的下沉操作:为满足最大堆的性质,需要将指定位置的数在二叉树的逻辑上,向下交换到合适的位置。
5.最大堆的构建:从层序遍历中最后一个非叶子节点开始,每个节点执行下沉操作,则可完成二叉树的构建。
在堆排序中,需要用到以上的有关于堆的知识,此时来讲解堆排序:
1.将无序数组构建为最大堆的形式,此时堆顶的数就是当前无序数组中最大的数。
2.将无序数组的最后一个数和第一个数交换,则最大的数被交换到了无序数组的最后,成为了有序数组的一部分。
3.将交换后的第一个数(也就是刚刚无序数组的最后一个数)进行下沉操作,以继续满足最大堆的性质。
4.重复上述的操作,直到整个数组排序完成。

排序代码

public static void heapSort(int[] arr)
	//从最后一个非叶子节点开始下沉操作,构建最大堆
    for (int i = (arr.length - 1 - 1) / 2; i >= 0; i--)
        siftDown(arr, i, arr.length);
    
    //对数组进行交换和下沉操作
    for (int i = arr.length - 1; i > 0; i--)
        swap(arr, 0, i);
        siftDown(arr, 0, i);
    

//下沉操作
private static void siftDown(int[] arr, int i, int length) 
	//保证此节点有左节点
    while (2 * i + 1 < length)
    	//左节点的索引
        int j = (i << 1) + 1;
        //判断是否有右节点,并筛选出两节点的最大值所在的索引
        if (j + 1 < length && arr[j + 1] > arr[j])
            ++j;
        
        //若节点的值小于节点的最大值,则结束循环
        if (arr[i] > arr[j])
            break;
        
        //交换两节点的值,并更改当前节点的索引
        swap(arr, i, j);
        i = j;
    

以上是关于Java堆排序的主要内容,如果未能解决你的问题,请参考以下文章

Java堆排序

Java堆排序

9 Java 堆排序

堆排序Java实现

堆排序及java版实现

Java实现堆排序和计数排序