堆排序算法

堆排序主要理解:大数向上叠 小数向下叠的操作  数组排序 (角标从0开始)  满的二叉树

package Algorithms;


import java.util.Random;

/**
 * 堆排序:
 *
 * 思路内容:堆排序  ----> 最大二叉树的排序(父节点是大于等于子节点的完全二叉树内容)
 * 公式:
 *      parentId = x/2 (向下取整)
 *      子节点 : 左节点 (2*parentId)
 *               右节点 (2*parentId+1)
 * 特点:
 *      从第一个元素进行开始构建(故第0是没有值)
 *      最大的max在第一个节点
 *
 * 时间复杂度:
 *      nlogM
 *
 * shiftUp的操作:
 *      向上比较
 *
 * shiftDown的操作
 *      向下比较操作
 *
 */
public class MaxHeap {
    private int[] arr;
    private int count;
    public MaxHeap(int capacity){
        arr = new int[capacity];
        count++;
    }
    /**
     * 获取堆长度
     * @return
     */
    public int getCount(){
        return count;
    }

    /**
     * 添加一个元素
     * @param oneElement
     */
    public void insertElement(int oneElement){
        arr[count] = oneElement;
        shiftUp(count);
        count++;
    }

    /**
     * 去掉最顶端值进行出堆操作,最终会出现意想不到的结果 :从大到小排序
     */
    public int removeMax (){
         int temp = arr[1];
         arr[1] = arr[count-1];
         count --;
        shiftDown(1);
         return temp;
    }

    /**
     * 去掉顶端值,将最后一个进行将第一个元素进行补上
     * @param k
     */
    private int shiftDown(int k) {
        while ((k*2)<=count){
            int temp = (k * 2);
            //比较2个节点内容
            if((temp+1) <= count && arr[temp] < arr[temp+1])
                temp =temp+1;
            if(arr[k] > arr[temp])
                break;
            SortTools.swapArr(arr,temp,k);
            k = temp;
        }
        return arr[k];
    }

    /**
     * 与父元素进行是否交换的操作内容
     * @param k
     */
    private void shiftUp(int k) {
        while (k>1 && arr[k/2]<arr[k]){
            SortTools.swapArr(arr,(k/2),k);
            k = k/2;
        }
    }


    public static void main(String[] args) {
        int z = 100;
        MaxHeap heap = new MaxHeap((z*2));
        for(int k=0;k<z;k++){
            heap.insertElement(new Random().nextInt(101));
        }
        //100  50  34  5  48
        /**
         *        100           1  + 2  = 1+1+1
         *     50    34         2  + 3  = 2+2+1
         *    5  48             4  + 5
         *                      8  + 6
         *    99  92  73  85  50  8  7  38  16  41
         */

        SortTools.printArr(heap.arr);

        int[] arr = new int[z];
        for(int k =0 ;k < z ;k++){
            arr[k] = heap.removeMax();
        }
        SortTools.printArr(arr);
        SortTools.isSortLeft(arr);
    }
}
/**
     * 校验排序结果是否正确
     * @param arr
     * @return
     */
    public static boolean isSortLeft(int arr[]){
        boolean flag= true;
        for(int k=0,total=arr.length ; k<(total-1) ; k++){
            if(arr[k]<arr[k+1]){
                flag = false;
                break;
            }
        }
        System.err.println("排序的结果  :  "+flag);
        return flag;
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值