堆排序

堆排序

堆排序的大概步骤如下:

1、构建最大堆。
2、选择顶,并与第0位置元素交换
3、由于步骤2的的交换可能破环了最大堆的性质,第0不再是最大元素,需要调用maxHeap调整堆(沉降法),如果需要重复步骤2

堆排序中最重要的算法就是maxHeap,该函数假设一个元素的两个子节点都满足最大堆的性质(左右子树都是最大堆),只有跟元素可能违反最大堆性质,那么把该元素以及左右子节点的最大元素找出来,如果该元素已经最大,那么整棵树都是最大堆,程序退出,否则交换跟元素与最大元素的位置,继续调用maxHeap原最大元素所在的子树。该算法是分治法的典型应用。具体代码如下:

public class HeapSort {

    public static void main(String[] args) {
        int[] array={9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 };
        System.out.println("Before heap:");
        System.out.println(Arrays.toString(array));

        heapSort(array);

        System.out.println("After heap sort:");
        System.out.println(Arrays.toString(array));
    }
    public static void heapSort(int[] array){
        if(array==null || array.length<=1){
            return;
        }//判断数组是不是为空,是不是只有一个元素

        buildMaxHeap(array);//建立堆

        for(int i=array.length-1;i>=1;i--){
            exchangeElements(array,0,i);//交换第一个和最后一个,最大推最大的值被交换到最小面

            maxHeap(array,i,0);
        }
    }
    public static void buildMaxHeap(int[] array){
        if(array==null || array.length<=1){
            return;
        }

        int half=array.length/2;
        for(int i=half;i>=0;i--){
            maxHeap(array,array.length,i);
        }
    }
    public static void maxHeap(int[] array,int heapSize,int index){
        int left=index*2+1;//左节点
        int right=index*2+2;//右节点

        int largest=index;//这个点就是左右节点的父节点
        if(left<heapSize && array[left]>array[largest]){
            largest=left;//只有左节点的索引还有数值比父节点大,交换索引
        }
        if(right<heapSize && array[right]>array[largest]){
            largest=right;//只有右节点的索引还有数值比父节点大,交换索引
        }
        if(index!=largest){//进行交换左节点或是右节点和父节点交换
            exchangeElements(array, index, largest);

            maxHeap(array, heapSize, largest);
        }
    }
    //交换左节点或是右节点和父节点交换数值
    public static void exchangeElements(int[] array,int index1,int index2){
        int temp=array[index1];
        array[index1]=array[index2];
        array[index2]=temp;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值