堆排序(Java实现)

堆排序概括:

堆排序(Heapsort)是指利用堆这种数据结构设计的一种排序算法。堆积是一个近似完全二叉树的结构,其实就是把数组元素想象为一颗二叉树,顺序按从上到下从左到右,但只是想象而已,并没有正真构建二叉树。这一棵想象的二叉树满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆排序算法描述:

将初始待排序关键字序列(R0,R1….Rn-1)构建成大顶堆,此堆为初始的无序区;
将堆顶元素R[0]与最后一个元素R[n-1]交换,此时得到新的无序区(R0,R1,……Rn-2)和新的有序区(Rn-1),且满足R[0,1…n-2]<=R[n-1];
由于交换后新的堆顶R[0]可能不再是大顶堆,因此需要对当前无序区(R0,R1,……Rn-2)调整为新的大顶堆,然后再次将R[0]与无序区最后一个元素交换,得到新的无序区(R0,R1….Rn-3)和新的有序区(Rn-2,Rn-1)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

堆排序算法的动态演示图如下:

                                          

堆排序的Java代码实现:

/**
 * 堆排序的Java代码实现
 */
public class HeapSort {
    public void heapSort(int[] arr) {

        if (arr == null || arr.length <= 0) {
            return;
        }

        //建立堆
        headBuild(arr);

        //循环遍历,交换最大值(根)到末尾
        for (int i = arr.length - 1; i >= 1; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            //交换后重新调整根为最大堆
            maxHead(arr, 0, i);
        }
    }

    /**
     * 建立堆
     *
     * @param arr
     */
    private void headBuild(int[] arr) {
        //这里(arr.length >> 1) - 1是二叉树的倒数第一个非叶子节点(可以用数学推导)
        //其中叶子节点不需要构建大顶堆,所以从倒数第一个非叶子节点往上遍历调整大顶堆即可
        for (int i = (arr.length >> 1) - 1; i >= 0; i--) {
            //构建大顶堆
            maxHead(arr, i, arr.length);
        }
    }

    /**
     * 构建大顶堆
     *
     * @param arr
     * @param index
     * @param length
     */
    private void maxHead(int[] arr, int index, int length) {
        //根子节点index的左子节点是(index << 1) + 1,右子节点是(index << 1) + 2(可以用数学推导)
        int l = (index << 1) + 1;
        int r = (index << 1) + 2;
        int largest = index;

        if (l < length && arr[l] > arr[largest]) {
            largest = l;
        }
        if (r < length && arr[r] > arr[largest]) {
            largest = r;
        }

        //若最大值不在根节点,则交换最大值到根节点
        if (largest != index) {
            int temp = arr[largest];
            arr[largest] = arr[index];
            arr[index] = temp;
            //递归把更改过的子节点调整为最大堆
            maxHead(arr, largest, length);
        }
    }
}
/**
 * 测试算法
 */
public class Main {

    public static void main(String[] args) {
        HeapSort hs = new HeapSort();
        int[] arr = {34, 1, 43, 2, 67, 55, 121, 2, 34, 23, 45, 11, 10, 88, 90};
        hs.heapSort(arr);
        for (int i = 0; i < arr.length; i++) {
            if (i != arr.length - 1) {
                System.out.print(arr[i] + ",");
            } else {
                System.out.println(arr[i]);
            }
        }
    }
}

代码运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值