堆排序

本文深入讲解堆排序算法的实现过程,通过具体代码演示如何构造和调整最大堆,从而完成数组的排序。文章详细解释了堆排序的核心思想,包括顶堆过程和数组位置调整,以及如何在保持堆性质的同时进行元素交换。
public class HeapSort
{
    public static void main(String[] args)
    {
        int array[] = {4, 6, 8, 5, 9};
        HeapSort heapSort = new HeapSort();
        heapSort.heapSort(array);
        System.out.println(Arrays.toString(array));
    }

    void heapSort(int array[])
    {
        //第一趟找顶堆的过程
        //首先,将最下方呈顶堆形式
        //依次向上,当到i=0是,形成最上方3个数为顶堆,但可能破坏了下方的顶堆,所以需要循环向下再形成顶堆
        for (int i = array.length / 2 - 1; i >= 0; i--)
        {
            maxHeap(array, i, array.length);
        }
        //形成了顶堆后,需要调节数组的位置
        //将array[0]的值即顶堆值,放到数组的最后位置
        //将array[0]的值即次顶堆值,放入数组的倒数第二的位置
        for (int j = array.length - 1; j > 0; j--)
        {
            int temp = array[j];
            array[j] = array[0];
            array[0] = temp;
            //顺序为:形成顶堆,调换数组位置,形成顶堆,调换数组位置
            //再次形成次顶堆时,其他位置已经在形成最顶堆的过程中安防在正确的位置
            //只需要将与最顶堆调换位置的array[0]的值,即i=0的非叶子节点进行正确的安防即可,即形成以i=0的顶堆
            maxHeap(array, 0, j);//因为数组的最后一个值已经为最大了,不需要动了,所以,每次数组的比较长度都--即j--
        }
    }

    static void maxHeap(int array[], int i, int length)
    {
        //i = 1时,正常一次顶堆
        //i = 0时,最上方形成顶堆,但可能破坏了下方的顶堆,所以需要for循环一直到最下方的非叶子节点
        for (int k = 2 * i + 1; k < length; k = k * 2 + 1)
        {
            int temp = array[i];
            if ((k + 1) < length && (array[k] < array[k + 1]))//左右比较
            {
                k++;
            }
            if (temp < array[k])//上下比较
            {
                array[i] = array[k];
                i = k;//下一层非叶子节点
            } else
            {
                break;//结束此次for循环中的i
            }
            array[k] = temp;//形成以非叶子节点i的形式顶堆
        }
        /*
        用while循环同for的作用,但是更能体现出堆排序的复杂度为    nlogn
        int k = 2 * i + 1;
        while (k < length)
        {
            int temp = array[i];
            if ((k + 1) < length && (array[k] < array[k + 1]))//左右比较
            {
                k++;
            }
            if (temp < array[k])//上下比较
            {
                array[i] = array[k];
                i = k;//下一层非叶子节点
            } else
            {
                break;//结束此次for循环中的i
            }
            array[k] = temp;//形成以非叶子节点i的形式顶堆
            k = k * 2 + 1;
        }
        * */
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值