数据结构-堆排序

堆排序:

学习网站:https://www.cs.usfca.edu/~galles/visualization/HeapSort.html

//先了解两个概念
// 大顶堆:每个节点的值都大于或者等于它的左右子节点的值。
// 小顶堆:每个节点的值都小于或者等于它的左右子节点的值。
//堆排序的基本思想是:
// 1、将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;
// 2、将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆;
// 3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。
// 最后,就得到一个有序的序列了
package com.suirui.sort.heapsort;
//先了解两个概念
// 大顶堆:每个节点的值都大于或者等于它的左右子节点的值。
// 小顶堆:每个节点的值都小于或者等于它的左右子节点的值。

import com.suirui.sort.SwapElem;

/**
 * Created by zongx on 2020/1/14.
 */
//堆排序的基本思想是:
// 1、将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;
// 2、将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆;
// 3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。
// 最后,就得到一个有序的序列了。
public class HeapSort {

    public void sort(int[] arr) {
        //1、构建大顶堆
        buildMaxHeap(arr,arr.length);
        //2、第一个值现在就是最大的,后面再依次对去除前一个值的数组进行建立堆
        // 此时,取第一个值比较困难,我们可以将第一个值与最后一个值交换,然后对length-1长度的数组,再建立最大堆,并再次交换
        for (int i = 0; i <= arr.length - 1; i++) {
            SwapElem.swap(arr,0,arr.length - 1- i);
            buildMaxHeap(arr,arr.length-i-1);
        }

    }

    private void buildMaxHeap(int[] arr,int len) {
        //从底部开始构建大顶堆,第一个底部树形结构是中间-1节点与最后两个节点,依次类推,直到整个数组变为大顶堆
        int i = len/2-1;//中间节点的选取,必须要能够在*2 +1或+2后包含最后一个数值
        for (; i>=0; i--) {
            //将以i作为根节点的树形结构,变为大顶堆
            buildMaxHeapHelper(arr,i,len);
        }
    }

    private void buildMaxHeapHelper(int[] arr, int i, int len) {
        int left = 2 * i + 1;//i节点的左孩子
        int right = 2 * i + 2;//i节点的右孩子

        int maxIndex = len-1;//孩子节点极值

        int largestNode = i;//默认当前i节点值最大,后边会进行最大堆排序
        //以i节点,进行最大堆排序
        //1、先比较根节点与左孩子的值,将大值节点坐标作为largestNode
        if(left <= maxIndex && arr[left] > arr[largestNode]){
            largestNode = left;//此处注意不要交换值,因为是取根节点与左右子树的最大值,所以还要比较右孩子
        }
        //2、比较根节点与左孩子的最大值和右孩子的值,将大值节点坐标作为largestNode
        if(right <= maxIndex && arr[right] > arr[largestNode]){
            largestNode = right;
        }
        //3、判断最大值坐标是否还是根节点坐标,如果发生了变化,则交换最大值和根节点坐标的值,然后递归这个值的新堆
        if (largestNode != i) {
            SwapElem.swap(arr,i,largestNode);
            buildMaxHeapHelper(arr,largestNode,len);//已经交换值,所以largestNode的坐标是要再进行排序的堆
        }

    }


}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值