逐句解释堆排序

Posted 月下赶路人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逐句解释堆排序相关的知识,希望对你有一定的参考价值。

//堆排序1
    private static int heapSize;//声明全局变量,记录堆中有多少元素
    private static Integer[] array;//声明全局变量,存储传来要排序的元素
    
    static void heapSort(Integer[] arr) 
        array = arr;
        //原地建堆
        heapSize = arr.length;
        //从最后一个非叶子节点向上构建最大堆(二叉堆的逻辑结构是一个完全二叉树,最后一个非叶子节点索引=节点数/2-1)
        for (int i = (heapSize >> 1) - 1; i >= 0; i--) 
            siftDown(i);
        
        //交换---堆顶元素和堆尾元素,直到堆中元素只剩1个
        while (heapSize > 1) 
            Integer tmp = arr[0];//堆顶元素
            heapSize--;
            arr[0] = arr[heapSize];
            arr[heapSize] = tmp;

            //对堆顶元素0位置进行下滤操作,恢复堆的性质
            siftDown(0);

        
    

//下滤---自底向上原地建堆
    private static void siftDown(int index) //传入要下滤的节点
        Integer element = array[index];//获取传入的节点的元素
        int half = heapSize >> 1;//将元素个数减半,判断,传入节点是否是叶子结点
        //以完全二叉树作为逻辑结构, 节点数量减半后的索引位置都是叶子节点
        while (index < half) //index位置必须非叶子节点
            //获取左孩子节点,不是叶子节点,左节点一定不为空
            int childrenIndex = (index << 1) + 1;
            int child = array[childrenIndex];//获取左孩子元素
            int rightIndex = childrenIndex + 1;//右孩子索引就是左孩子+1
            //判断右孩子索引在数组容量范围内, 右孩子节点大于左孩子节点
            if (rightIndex < heapSize && array[rightIndex]- child > 0) 
                //将childrenIndex指向值更大的孩子
                childrenIndex = rightIndex;
                //将child变为更大的值
                child = array[rightIndex];
            
            //判断传入元素大于>=孩子节点
            if (element - child >= 0) 
                break;//跳出
            
            //到这里代表传入元素比孩子节点元素小
            array[index] = child;//就将对应的孩子换到父节点的索引位置
            index = childrenIndex;//再将索引换成原本的孩子节点
        
        array[index] = element;//索引元素最后在堆中的位置
    

以上是关于逐句解释堆排序的主要内容,如果未能解决你的问题,请参考以下文章

逐句解释堆排序

逐句解释堆排序

原地堆排序

挖掘算法中的数据结构:堆排序之 二叉堆(Heapify原地堆排序优化)

scratch图解排序算法:插入排序冒泡排序选择排序归并排序快速排序堆排序

堆排序