【数据结构】堆排序原理及实现

1.堆是一颗完全二叉树。

2.建立大根堆进行排序步骤

 

1)从第一个非叶子点开始堆化,一直到根节点

2)每次将根节点(最大值)放到最后面 重新堆化

/**
 * @Description:堆排
 * @Author: cckong
 * @Date:
 */
public class heapsort {
    public static void main(String[] args) {
        int[] arr = {5, 3, 2, 6, 7, 8, 9, 10, 1, 12, 4, 21};
        int len=arr.length;
        //从第一个非叶子节点开始堆化 一直到根节点
        for(int i=len/2-1;i>=0;i--){
            heapify(arr,i,len);
        }
        for(int tmp:arr) System.out.print(tmp+" ");
        //开始排序
        for(int i=len-1;i>0;i--){
            swap(arr,0,i);//将大根堆的根节点(目前的最大值) 放到当前最后一位
            heapify(arr,0,i);//将剩余的结点重新堆化 长度减少1位
        }
        System.out.println();
        for(int tmp:arr) System.out.print(tmp+" ");
    }
    /**
    * @Description: 堆化操作
    * @Param:  建堆数组arr 开始堆化的位置i    最大长度len
    * @return:  null
    * @Author: cckong
    * @Date: 2021/4/12
    */
    public static void heapify(int[] arr,int i,int len){
        int tmp=arr[i];
        //注意for循环条件 从根的左子开始 每次都要去子的子结点(孙子结点)所以是k=2k+1
        for(int k=2*i+1;k<len;k=2*k+1){
            if(k+1<len&&arr[k+1]>arr[k]) k++;//父 左子 右子 在左右子选出最大的那个变为新父节点
            if(arr[k]>arr[i]){
                arr[i]=arr[k];//将当前i值替换成k值
                i=k;//i变k继续向下堆化
            }else {break;}
        }
        arr[i]=tmp;//最后一步进行赋值
    }
    /**
    * @Description: 交换函数
    * @Param:  需要排序的数组arr   交换的位置 i j
    * @return:  null
    * @Author: cckong
    * @Date: 2021/4/12
    */
    public static void swap(int[] arr,int i,int j){
        int tmp=arr[i];arr[i]=arr[j];arr[j]=tmp;
    }
}

3.小根堆只要改上面堆化的大于号改为小于号

/**
     * @Description: 堆化操作
     * @Param:  建堆数组arr 开始堆化的位置i    最大长度len
     * @return:  null
     * @Author: cckong
     * @Date: 2021/4/12
     */
    public static void heapify(int[] arr,int i,int len){
        int tmp=arr[i];
        //注意for循环条件 从根的左子开始 每次都要去子的子结点(孙子结点)所以是k=2k+1
        for(int k=2*i+1;k<len;k=2*k+1){
            if(k+1<len&&arr[k+1]<arr[k]) k++;//父 左子 右子 在左右子选出最大的那个变为新父节点
            if(arr[k]<arr[i]){
                arr[i]=arr[k];//将当前i值替换成k值
                i=k;//i变k继续向下堆化
            }else {break;}
        }

原文地址:https://www.cnblogs.com/cckong/p/14648884.html