堆排序

堆排序的基本介绍

  1. 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它是最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
    2)堆是具有以下性质的完全二叉树:
            大顶堆:每个节点的值都大于或定域其左右子节点的值
            小顶堆:每个节点的值都小于或等于其左右子节点的值
    注意:没有要求节点的左右子节点的值的大小关系,一般升序采用大顶堆,降序采用小顶堆。

堆排序的基本思想

升序排列
1.将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点
2.将其与末尾元素进行交换,此时末尾就为最大值
3.然后将剩余n-1个元素重新构造成一个堆,这样会得到n的元素的次小值。如此反复执行,便可得到一个有序序列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现
import java.util.Arrays;

/**
 * 堆排序
 */
public class HeapSort {

    public static void main(String[] args) {
        int[] arr = {1,3,6,8,10,14};
        heapSort(arr);
    }
    public static void heapSort(int[] arr){
        System.out.println("堆排序");

        //构建初始堆,将一个无序堆构建成一个大顶堆
        for (int i = arr.length/2-1; i>=0; i --){
            adjustHeap(arr,i,arr.length);
        }
        System.out.println("初始化大顶堆 : "+Arrays.toString(arr));
        //将堆顶元素和末尾元素进行交换,将最大元素放置到数组末端
        for (int i = arr.length-1; i > 0; i-- ){
            //堆顶元素和末尾元素交换
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;

            adjustHeap(arr,0,i);
        }
        System.out.println(Arrays.toString(arr));

    }

    /**
     * 完成 节点i 对应的非叶子节点的树调整成大顶堆
     * @param arr  需要调整的数组
     * @param i    非叶子节点在数组中索引
     * @param length  表示对多少个元素进行调整
     */
    public static void adjustHeap(int[] arr, int i, int length){
        //查看当前节点i的左右字数  左子树 2*i+1 右子树 2*i+2
        for (int k = i*2+1; k< length; k = k*2+1){
            //判断左右子树的大小,并获取其最大值
            //k+1 说明右子树存在  arr[k]<arr[k+1] 说明右子树大于左子树
            if (k+1 < length && arr[k] < arr[k+1]){
                k++;//此时用k下标记录右子树
            }
            //子节点 大于父节点 交换位置
            if (arr[k] > arr[i]){
                int temp = arr[k];
                arr[k] = arr[i];
                arr[i] = temp;
                i = k;//***
            }
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值