排序算法-选择排序之堆排序

本文介绍了堆的概念,包括大根堆和小根堆,并详细解释了堆排序的基本思想及步骤。通过对堆排序算法的深入剖析,包括构建堆、排序过程等关键环节,展示了如何使用Java实现堆排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆是一种除了底层节点外的完全填满的二叉树,底层可以不完全,左到右填充。堆在实现优先队列的时候很有用。堆又分为大根堆和小根堆。大根堆的父节点的值大于等于两个子节点的值。小根堆的父节点的值小于等于两个子节点的值。
堆排序的思想是:每次从堆中取出最小(大)值,将取出的元素按顺序排到数组中,这样所有的元素就是从小到大(从大到小)排列在数组中。我们可以把删除最小值得到的元素重新排在一个数组中,或者排在该数组的末尾,减少空间。对堆的操作不是很难,插入就是将元素进行上滤。删除最小值相当于把树根置为空穴,将这个空穴下滤,下滤通过,两个子节点中最小的元素和空穴进行交换位置,下滤到最下面一层时,将数组末尾的元素放到空穴,保证每层是从左到右插入数据,最后将该元素上滤,保证父元素比两个子元素大。

代码

package com.creat.sort;

import org.junit.Test;

/**
 * Created by whz on 2017/8/23.
 */
public class HeapSort {

    @Test
    public void test(){
        Integer[] array = new Integer[]{10,54,55,47,50,20,41,33,40,28,70};
        Integer[] newArray = new Integer[array.length+1];
        buildHeap(array,newArray);
        sort(newArray,array);
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
    //排序
    public static <T extends Comparable<? super T>> void sort(T[] array,T[] newArray){
        int length = array.length;
        for(int i = 0; i < newArray.length; i++){
            newArray[i] = deleteMin(array,newArray.length -i );
        }
    }
    //构建小根堆
    public static <T extends Comparable<? super T>> void buildHeap(T[] array,T[] newArray){
        newArray[0] = null;
        for(int i = 1; i <= array.length; i++){
            insert(newArray,array[i-1],i);
        }
    }
    //删除最小值
    private static <T extends Comparable<? super T>> T deleteMin(T[] array,int size){
        T result = array[1];
        array[1] = null;
        int index = 1;
        while(index*2 < array.length-1 && array[index*2] != null ){
            if(array[index*2+1] == null || array[index*2].compareTo(array[index*2+1]) < 0){
                array[index] = array[index*2];
                index *= 2;
            }else{
                array[index] = array[index*2+1];
                index = index*2+1;
            }
        }
        insert(array,array[size],index);
        array[size] = null;
        return result;
    }
    //插入
    private static <T extends Comparable<? super T>> void insert(T[] array,T value,int place){
        if(((double)place)/2%1 == 0){
            int index = place;
            if(index!=1 && array[index/2].compareTo(value) > 0 ){
                array[index] = array[index/2];
                insert(array,value,index/2);
            }else {
                array[index] = value;
            }
        }else {
            int index = place;
            if (index!=1 && array[(index-1)/2].compareTo(value) > 0 ){
                array[index] = array[(index-1)/2];
                insert(array,value,(index-1)/2);
            }else {
                array[index] = value;
            }
        }
    }
}

堆排序的时间复杂度,最坏,平均,最好都为O(Nlog2N)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值