堆排序的玩法

堆排序一共有两种风格
都以升序排序为例

  1. 将待排序数组建成一个小堆,每次取堆顶元素后放入一个数组中。然后再向下调整继续进行。
  2. 把数组建成一个大堆,堆顶就是当前数组的最大值,然后把堆顶元素和最后一个元素进行互换,再把最后一个元素从堆里面删除,

第一种:

public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 9, 1, 2};
        System.out.println((Arrays.toString(insertsort(arr))));
    }
    public static int[] insertsort(int[] arr) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();//首先建立一个小堆
        for (int i = 0; i < arr.length; i++) {//再将待排序数组中的每个元素入队列
            queue.offer(arr[i]);
        }
        int[] array = new int[arr.length];//再创建一个新的数组来存放堆顶元素
        for (int i = 0; i < array.length; i++) {//循环出堆顶元素放到新数组中
            array[i] = queue.poll();
        }
        return array;
    }

第二种:

 public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 9, 1, 2};
        insertsort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void insertsort(int[] arr) {
        //首先建大堆
        creatheap(arr);
        for(int i = 0;i<arr.length;i++){//然后循环交换堆顶元素和堆尾元素
            swap(arr,0,arr.length-1-i);//注意交换的是堆顶元素和堆尾元素,而非数组尾元素。
            //交换完之后还要进行向下调整
            shiftdown(arr,0,arr.length-1-i);//交换完之后此时堆中的有效元素就要少一个,
        }
    }
    public static void swap(int[] arr,int i,int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    private static void creatheap(int[] arr) {
        int index = (arr.length-1-1)/2;//从倒数第一个非叶子节点开始进行向下调整
        for(;index>=0;index--){
            shiftdown(arr,index,arr.length);
        }

    }
    private static void shiftdown(int[] arr, int index, int heaplength) {
        int parent = index;
        int child = parent*2+1;
        while(child<heaplength){
            if(child+1<heaplength&&arr[child]<arr[child+1]){
                child = child+1;
            }
            if(arr[parent] < arr[child]){
                int tmp =  arr[parent];
                arr[parent] = arr[child];
                arr[child] = tmp;
            }else{
                break;
            }
            parent = child;
            child = parent*2+1;
        }
    }

第一种风格有一点缺陷就是需要开辟额外的空间,而第二种则不需要。
堆排序也是不稳定排序。因为在向下调整的时候会打乱顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值