算法-堆排序-原理与Java代码实现

以大顶堆举例:

  • 1、首先用构造一个初始的大顶堆
  • 2、然后将堆顶和堆尾的一个元素交换,交换后的队尾元素加入排序队列尾
  • 3,重新构建堆
  • 4,重复步骤2-3

理解上就是每次选取堆的最大值,之后将最大值删除,重构堆再重复以上操作

  • 在Java中我们常用优先队列构建大顶堆和小顶堆
PriorityQueue<Integer> pq = new PriorityQueue<>();
  • 在后边的括号中使用Lamba表达式调整大顶堆和小顶堆

使用代码实现一个堆排序如下

package sort;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @auther alex
 * @description for test
 * @data 2021/3/10
 **/
public class HeapSort {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int len = 4;
        int[] test = new int[len];
        for(int i = 0;i < len;i++){
            test[i] = scanner.nextInt();
        }
        headSort(test);
        System.out.println(Arrays.toString(test));
    }
    //堆排序函数
    private static void headSort(int[] arr){
        //创建初始堆,从第一个非叶子节点开始调整堆
        for(int i = (arr.length - 1) / 2;i >= 0;i--){
            adjustHeap(arr,i,arr.length);
        }

        //交换堆顶和堆底的元素,删除堆底最大值入排序序列
        //调整堆结构
        //调整堆结构+交换堆顶元素与末尾元素
        for (int i = arr.length - 1; i > 0; i--) {
            //将堆顶元素与末尾元素进行交换
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;

            //重新对堆进行调整
            adjustHeap(arr, 0, i);
        }
    }
    //调整堆
    private static void adjustHeap(int[] arr,int parent,int length){
        //将temp作为父节点
        int temp = arr[parent];
        //左孩子
        int lChild = 2 * parent + 1;

        while (lChild < length) {
            //右孩子
            int rChild = lChild + 1;
            // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
            if (rChild < length && arr[lChild] < arr[rChild]) {
                lChild++;
            }

            // 如果父结点的值已经大于孩子结点的值,则直接结束
            if (temp >= arr[lChild]) {
                break;
            }

            // 把孩子结点的值赋给父结点
            arr[parent] = arr[lChild];

            //选取孩子结点的左孩子结点,继续向下筛选
            parent = lChild;
            lChild = 2 * lChild + 1;
        }
        arr[parent] = temp;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值