堆排序(超详细图解 java版)

简介: l) 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为0(nlogn),它也是不稳定排序。

堆排序基本介绍


l) 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为0(nlogn),它也是不稳定排序。


2)堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,注意:没有要求结点的左孩子的值和右孩子的值的大小关系。


3)每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆


4)大顶堆举例说明




5)小顶堆举例说明



6) 一般升序采用大顶堆,降序采用小顶堆


堆排序基本思想


堆排序的基本思想是:.


1)将待排序序列构造成一个大顶堆


2)此时,整个序列的最大值就是堆顶的根节点。


3)将其与末尾元素进行交换,此时末尾就为最大值。


4)然后将剩余n-1 个元素重新构造成-一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。


可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了.


堆排序步骤图解说明:


要求:给你一个数组{4,6,8,5,9}, 要求使用堆排序法,将数组升序排序。


步骤一  构造初始堆。将给定无序序列构造成一个大顶堆( 一般升序采用大顶堆,降序采用小顶堆)。


原始的数组[4, 6, 8, 5, 9]


1) .假设给定无序序列结构如下





2) .此时我们从最后-个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点

arr.length/2-1=5/2-1=1 ,也就是下面的6结点) , 从左至右,从下至上进行调整。





3) .找到第二个非叶节点4,由于[4,9,8]中9元素最大, 4和9交换。





4)这时,交换导致了子根[4,5,6]结构混乱,继续调整, [4,5,6]中6最大,交换4和6。





此时,我们就将一个无序序列构造成了一一个大顶堆。


步骤二  将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。


1)将堆顶元素9和末尾元素4进行交换






2) 重新调整结构,使其继续满足堆定义





3) 再将堆顶元素8与末尾元素5进行交换,得到第二大元素8.





4)后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序




再简单总结1下堆排序的基本思路:


1).将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;


2).将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;


3).重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,


直到整个序列有序。


堆排序代码实现


要求:给你一个数组{4,6,8,5,9} ,要求使用堆排序法,将数组升序排序。

import java.util.Arrays;
public class HeapSort {
    public static void main(String[] args) {
        int arr[] = {4, 6, 8, 5, 9};
        System.out.println("排序前" + Arrays.toString(arr));
        heapSort(arr);
        System.out.println("排序后" + Arrays.toString(arr));
    }
    public static void heapSort(int arr[]) {
        int temp = 0;
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            adjustHeap(arr, i, arr.length);
        }
        /**
         * 将堆项元素与末尾元素交换,将最大元素"沉"到数组末端;
         * 重新调整结构,使其满足堆定义,然后继续交换堆项元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
         */
        for (int j = arr.length - 1; j > 0; j--) {
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr, 0, j);
        }
    }
    /**
     * 将一个数组(二叉树)调整成一个大根堆
     * 功能:完成将以i对应的非叶子结点的树调整成大顶堆
     * 举例int arr[]={4, 6,8,5,9};=>i=1=> adjustHeap=>得到{4,9,8,5, 6}
     * 如果我们再次调用adjustHeap 传入的是i=0=>得到{4,9, 8,5,6}=> {9,6,8,5, 4}
     *
     * @param arr    待调整的数组
     * @param i      表示非叶子结点在数组中索引
     * @param length 表示对多少个元素继续调整,length 是在逐渐的减少
     */
    public static void adjustHeap(int arr[], int i, int length) {
        int temp = arr[i];//先取出当前元素的值,保存在临时变量
        //开始调整.
        //说明:k=i*2+1k是i结点的左子结点
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
            if (k + 1 < length && arr[k] < arr[k + 1]) {
                k++;
            }
            if (arr[k] > arr[i]) {
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;
    }
}


相关文章
|
存储 搜索推荐 算法
堆排序详细讲解(一文足矣JAVA)
堆排序详细讲解(一文足矣JAVA)
|
搜索推荐 算法 Java
堆排序实战:轻松实现高效排序,附详细Java代码
嗨,大家好!我是小米,一名热爱技术分享的程序员。今天要带大家了解堆排序——一种基于二叉堆的数据结构,具有O(n log n)时间复杂度的选择排序算法。堆排序分为构建大顶堆和排序两个阶段:先建堆使根节点为最大值,再通过交换根节点与末尾节点并调整堆来逐步排序。它稳定高效,空间复杂度仅O(1),适合对稳定性要求高的场合。虽然不如快速排序快,但在避免递归和节省空间方面有优势。一起动手实现吧!如果有任何疑问,欢迎留言交流!
277 2
|
搜索推荐 算法 Java
Java中的快速排序、归并排序和堆排序是常见的排序算法。
【6月更文挑战第21天】Java中的快速排序、归并排序和堆排序是常见的排序算法。快速排序采用分治,以基准元素划分数组并递归排序;归并排序同样分治,先分割再合并有序子数组;堆排序通过构建堆来排序,保持堆性质并交换堆顶元素。每种算法各有优劣:快排平均高效,最坏O(n²);归并稳定O(n log n)但需额外空间;堆排序O(n log n)且原地排序,但不稳定。
122 3
堆排序(java)
堆排序(java)
|
算法 Java
<八大排序>万字详解(Java实现).插入排序、希尔排序、堆排序、快速排序、归并排序、计数排序...
<八大排序>万字详解(Java实现).插入排序、希尔排序、堆排序、快速排序、归并排序、计数排序
70 0
|
搜索推荐 算法 Java
java排序算法:快速排序、归并排序、堆排序等
排序算法:快速排序、归并排序、堆排序等
191 0
|
存储 算法 Java
数据结构——堆、堆排序和优先级队列(代码为Java版本)
数据结构——堆、堆排序和优先级队列(代码为Java版本)
|
人工智能 算法 搜索推荐
java基础算法系列(四)(堆排序的简单讲解)
java基础算法系列(四)(堆排序的简单讲解)
|
算法 搜索推荐 Java
【算法】堆排序的原理与Java实现
堆排序(Heap Sort)是一种基于堆数据结构的排序算法。堆是一种完全二叉树,其中父节点的值总是大于(或小于)其子节点的值。堆排序的基本思想是先将待排序的数组构建成一个最大堆(或最小堆),然后重复从堆顶取出最大(或最小)元素,放到已排序的部分,再调整剩余元素构建新的堆,直到所有元素都被放置到正确的位置。
170 0
|
Java 测试技术 vr&ar
大顶堆升序、小顶堆降序的堆排序(以Java描述为例版本)
大顶堆升序、小顶堆降序的堆排序(以Java描述为例版本)
294 0

热门文章

最新文章