Python 每日一记257>>>Java实现堆排序算法

什么是堆排序算法

利用堆数据结构进行排序(从小到大)

  1. 给定一个数组,将数组元素直接复制进堆数组中
  2. 然后对数据进行下沉操作,使得堆数据有序
  3. 将第一个元素和最后一个元素交换,此时第一个元素是小的,最后一个元素是最大的,表明最后大的元素归位,然后在除开最后一个元素的堆内对第一个元素进行进行下沉,以此类推,直到所有的元素归位

Java代码

/**
 *堆排序算法
 */

package mypackage;
import java.util.Arrays;

class Heapsort{
//比较数组元素的大小
    public static boolean less(Comparable[] heap, int i, int j){
        return heap[i].compareTo(heap[j])<0;
    }
//交换值
    public static void exchang(Comparable[] heap, int i, int j){
        Comparable temp=heap[i];
        heap[i]=heap[j];
        heap[j]=temp;
    }
//根据原数组创建堆,先整体复制,然后再使用sink使得堆有序,怎么有序呢?那就是根根节点最大,且大于左右子节点,但是左右字节点大小没有要求
// 注意堆数组的元素是从索引1开始的
    public static void creatheap(Comparable[] souce, Comparable[] heap){
        System.arraycopy(souce,0,heap,1,souce.length);
//        从heap.length/2索引开始,对小于这个索引的元素进行下沉算法,
//        为什么呢,因为heap.length/2之前的元素是非叶子节点,heap.length/2之后的元素是叶子节点
//        叶子节点就是没有子节点的节点,不需要再下沉调整啦,
//        关键是要理解为什么heap.length/2之前的元素是非叶子节点,heap.length/2之后的元素是叶子节点
        for (int i = heap.length/2; i>0 ; i--) {
            sink(heap,i,heap.length-1);
        }
    }

//    下沉算法
//    target表示对那个索引的元素进行下沉
//    range表示最大索引值
    public static void sink(Comparable[] heap, int target, int range) {
//        while(target还有子节点的情况下)
//        如果有有右子节点,比较左右子节点,取为较大值,如果没有右子节点,将左子节点作为较大值
//        将较大值与taget索引处的值交换,这就是下沉
        while (2*target<=range){
            int max;
            if (2*target+1<=range){
                if (less(heap,2*target,2*target+1)){
                    max=2*target+1;
                }else {
                    max=2*target;
                }
            }else {
                max=2*target;
            }
            if (!less(heap,target,max)) {
                break;
            }else {
                exchang(heap, target, max);
                target = max;
            }
        }
    }

//    排序算法,对元数组排序
    public static void sort(Comparable[] source){
//        先创建堆,注意大小为source.length+1,因为第一个元素从索引1开始
        Comparable[] heap =new  Comparable[source.length+1];
        creatheap(source,heap);
//        起始最大索引
        int N=heap.length-1;
//        while(最大索引不等于1)
//        先交换第一个元素和最后一个元素,也就是将最大元素放到最后去,这元素就算归位了,此时堆是无序的。
//        然后N--,也就是最大索引-1了,然后下沉算法就排除最大元素了,下沉算法之后,堆变为有序,且第二大的元素在根节点处
//        第二次循环,将第二大的元素在倒数第二个位置,这个元素也归位了,然后再N--,sink
//        反复执行后,元素就从先到大排序了

        while (N!=1){
            exchang(heap,1,N);
            N--;
            sink(heap,1,N);
        }
//        最后复制回元数组
        System.arraycopy(heap,1,source,0,source.length);
    }
}

//测试
public class MyJava {

    public static void main(String[] args) {
        Integer[] arr={9,8,7,6,5,4,3,2,1};
        Heapsort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

在这里插入图片描述
结果正确

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值