资讯专栏INFORMATION COLUMN

堆排序Java实现(递归方式&非递归方式)

jzman / 1075人阅读

摘要:很早就学习了堆排序但当时没有用代码实现,现在再去想实现已经忘光光啦,于是就去网上搜了一番,发现没有一篇我能认真看完的文章,没办法就是没耐心,就是笨呗。。。

很早就学习了堆排序但当时没有用代码实现,现在再去想实现已经忘光光啦┑( ̄Д  ̄)┍,于是就去网上搜了一番,发现没有一篇我能认真看完的文章,没办法就是没耐心,就是笨呗。。。好了,言归正传= ̄ω ̄=

了解概念

首先明白什么是堆,什么是完全二叉树,什么是大顶堆,相信百度一下很容易理解o(^▽^)o。

堆可以用数组来存储,如下图,数组 a[0,...,9] 表示一个堆在数组中的存储模式。数组中下标为i的节点的子节点下标分别为2*i+12*i+2,下标为j的子节点的父节点下标为(j-1)/2

算法描述

将待排序数组构建成一个大顶堆,也就是变换原始数组中元素的位置,使之满足大顶堆的定义。

将堆顶节点与堆中末尾节点交换,也就是数组的首尾元素交换,此时末尾节点已为最大元素,考虑剩余节点形成的堆。

将最新的堆重新构造成大顶堆。

重复第2步、第3步直到堆中节点全部输出。

建议不明白的同学观看视频https://www.bilibili.com/vide...

算法实现
public class HeapSort {

    public static void heapSort(int[] array) {
        array = buildMaxHeap(array); //初始建堆,array[0]为第一趟值最大的元素
        for (int i = array.length - 1; i >= 1; i--) {
            int temp = array[0];  //将堆顶元素和堆底元素交换,即得到当前最大元素正确的排序位置
            array[0] = array[i];
            array[i] = temp;
            adjustHeap1(array, 0, i);  //整理,将剩余的元素整理成大顶堆
        }
    }

    //自下而上构建大顶堆:将array看成完全二叉树的顺序存储结构
    private static int[] buildMaxHeap(int[] array) {
        //从最后一个节点array.length-1的父节点(array.length-1-1)/2开始,直到根节点0,反复调整堆
        for(int i=(array.length-2)/2;i>=0;i--){
            adjustHeap1(array, i, array.length);
        }
        return array;

    }

    //自上而下调整大顶堆(非递归)
    private static void adjustHeap1(int[] array, int k, int length) {
        int temp = array[k]; //堆顶节点
        for (int i = 2*k+1; i <= length - 1; i = 2*i+1) {    //i为初始化为节点k的左孩子,沿节点较大的子节点向下调整

            if (i+1< length && array[i] < array[i + 1]) {  //如果左孩子小于右孩子
                i++;   //则取右孩子节点的下标
            }
            if (temp >= array[i]) {  //堆顶节点 >=左右孩子中较大者,调整结束
                break;
            } else {   //根节点 < 左右子女中关键字较大者
                array[k] = array[i];  //将左右子结点中较大值array[i]调整到双亲节点上
                k = i; //【关键】修改k值,以便继续向下调整
            }
        }
        array[k] = temp;  //被堆顶结点的值放人最终位置
        
    }

    //自上而下调整大顶堆(递归)
    private static void adjustHeap2(int[] array, int k, int length) {
        int k1=2*k+1;  
        if(k1length-1||array[k]>=array[k1]){
            return;
        }else{
            int temp = array[k];  //将堆顶元素和左右子结点中较大节点交换
            array[k] = array[k1];
            array[k1] = temp;
            adjustHeap2(array,k1,length);
        }
    }
    
    

    public static void main(String[] args) {
        int[] a = {87,45,78,32,17,65,53,9,122,133};
        heapSort(a);
        System.out.println(Arrays.toString(a));
    }
}
算法复杂度

堆排序时间计算分两部分,构建堆时间复杂度O(n),调整堆时间复杂度O(nlogn),总的时间复杂度O(nlogn),堆排序为就地排序,空间复杂度O(1)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72593.html

相关文章

  • 排序

    摘要:计算机算法理论简介建立初始堆首末元素互换即得到最大元素放入数组最末尾调整堆第二步的操作明显会将堆破坏所以需要调整堆跳回第二步建立初始堆在建堆之前需要将数组转成二叉树图方便理解如果将父左子右子当做树的最小单元组称为父子单元那么只需要保证每个父 @(Study)[计算机, 算法] 理论简介 建立初始堆 首末元素互换, 即得到最大元素放入数组最末尾. 调整堆. 第二步的操作明显会将堆破坏,...

    tangr206 评论0 收藏0
  • 数据结构与算法——常用数据结构及其Java实现

    摘要:亦即总结常见的的数据结构,以及在中相应的实现方法,务求理论与实践一步总结到位。中,使用链表作为其基础实现。其限制是仅允许在表的一端进行插入和删除运算。 前言 仿佛一下子,2017年就快过去一半了,研一马上就要成为过去式了,我打算抓住研一的尾巴,好好梳理一下数据结构与算法,毕竟这些基础知识是很重要的嘛。所以准备在这里搞一个系列的文章,以期透彻。 本系列将采用Java语言来进行描述。亦即总...

    RiverLi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<