堆排序 O(nlogn)

堆排序的思路:将要排序的数组先构成一个大顶堆(此时除了顶点,其他还是乱序的),将第一个元素与最后一个元素交换,再对n-1个元素堆排序,依次类推就能构成一个从小到大的数组

package cn.stu.test;

import java.util.Arrays;

public class HeadSort {

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * 对第k个元素进行堆排序
     * @param arr
     * @param k
     * @param length需要排序的数组的长度,随着不断地将第一个元素移到数组后面,这个长度会逐渐变小
     */
    public static void headSortNumber(int[] arr, int k, int length) {
        int i = (length + 1) / 2 - 1;
        while (k <= i) {
            int t = k * 2 + 1;
            if (t + 1 <= length && arr[t] < arr[t + 1]) {//如果左子结点小于右子结点,k指向右子结点
                t += 1;
            }

            if (arr[k] > arr[t])//如果子节点小于父节点,直接跳过
                break;

            swap(arr, k, t);
            k = t;
        }
    }

    public static void headSort(int[] arr) {
        //构建一个堆
        for (int j = arr.length / 2 - 1; j >= 0; j--) {
            headSortNumber(arr, j, arr.length - 1);
        }
        //进行堆排序
        for (int j = arr.length - 1; j > 0; j--) {
            swap(arr, j, 0);
            headSortNumber(arr, 0, j - 1);
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[] { 43, 22, 21, 23, 67, 54, 78, 92, 34, 11, 36 };
        System.out.println(Arrays.toString(arr));
        System.out.println("************************************");
        headSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

优化:headSortNumber每次执行的时候,频繁的交换操作会降低执行效率,我们可以采用替代交换为赋值。

public static void headSortNumber(int[] arr, int k, int length) {
        int i = (length + 1) / 2 - 1;
        int temp = arr[k];
        while (k <= i) {
            int t = k * 2 + 1;
            if (t + 1 <= length && arr[t] < arr[t + 1]) {
                t += 1;
            }

            if (temp > arr[t])
                break;

            arr[k] = arr[t];
            k = t;
        }
        if(temp != arr[k]){
            arr[k] = temp;
        }
    }

总结:堆排序是一种不稳定的排序方式,执行效率是O(nlogn),借用堆的结构,巧妙地进行排序。重点要理解堆排序时,子节点和父节点的关系。

注意:

  • 可以借用笔纸演算来帮助理解堆排序的过程
  • 涉及数组的时候要注意防止数组越界
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值