java 实现堆排序

299 篇文章 1 订阅

堆排序作为八大排序中较为重要的一种,是每个程序员必须要会并且掌握的
具体思路如下:
首先给定需要排序的数组,构建原始堆

在这里插入图片描述
将原始堆调整为大顶堆,思路是这样的,找到第一个非叶子结点(6),判断 6 的左右子树,将左右子树中大的那个与 6 进行交换,然后是第二个飞叶子节点(4),最后是根节点(5),与结点 6 进行交换,结果如下:
在这里插入图片描述
此时构造出大顶堆,然后进行对排序的第二步,交换根节点与末尾元素
在这里插入图片描述

6 是确定好位置的,脱离整个堆,重新调整堆结构,使它还是成为一个大顶堆
在这里插入图片描述
此时继续交换,根节点与最后的结点交换
在这里插入图片描述
调整堆结构
在这里插入图片描述
同理,最后得出结果:
在这里插入图片描述
代码如下:

import java.util.*;


public class Main {
    public static void main(String[] args) {
        int[] a = new int[]{0, 1, 9, 7, 5, -4, 85, 12};
        System.out.println("排序前:" + Arrays.toString(a));
        heapSort(a);//开始堆排序
        System.out.println("排序后:" + Arrays.toString(a));

    }

    private static void heapSort(int[] a) {
        //第一步,构建大顶堆
        for (int i = a.length / 2 - 1; i >= 0; i--) {
            adjustHeap(a, i, a.length);//调整堆结构,使整个堆变成一个大顶堆
        }
        // 第二步,交换位置
        for (int i = a.length - 1; i > 0; i--) {
            swap(a, i, 0);//交换首位元素
            adjustHeap(a, 0, i);//调整大顶堆
        }
    }

    private static void swap(int[] a, int x, int y) {
    //由于 java 中没有自带的 swap 函数,所以可以自己写一个,
    //当然代码很简单,不写也没问题
    
        int temp = a[x];
        a[x] = a[y];
        a[y] = temp;
    }

    private static void adjustHeap(int[] a, int i, int length) {
        int temp = a[i];//先将当前元素取出来
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//每次向下调整
        //取得是每个根节点的左孩子,所以 k = k * 2 + 1
            if(k + 1 < length && a[k] < a[k + 1]) {
            //如果左子树的值小于右子树
                k ++;//让右子树交换
            }
            if(a[k] > temp) {//如果当前子树的值大于根节点,此时我们让子节点上调
                a[i] = a[k];//上调
                i = k;//记录位置
            } else break;
        }
        a[i] = temp;//再将该位置赋值
    }


}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_努力努力再努力_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值