• 堆排序


    大顶堆的定义:每一个父节点都大于其子结点,根结点是最大的结点

    数组转换为堆:层次遍历,第n层填满2^(n-1)次个,最后一层可以填满也可以不填满

    第i个结点的左子结点为2*i+1 右子结点为2*i+2

    堆结点的基本思想:将数组构造为大顶堆,把根结点放到无序数组的最后

    剩余的元素无序,继续构造大顶堆,将根节点放到无序数组后

    …………

    重复以上步骤 最后可以得到一个有序数组

    堆排序的完整代码如下:

     public static void heapSort(int[] arr)
            {
                int temp;
                //最后一个非叶子结点:arr.Length / 2 - 1
                for (int i = arr.Length / 2 - 1; i >= 0; i--)
                {
                    adjustHeap(arr, i, arr.Length);
                }//for循环结束后得到了第一个大顶堆
                for (int j = arr.Length-1; j > 0; j--)
                {
                    //交换 把根节点沉到最后
                    temp = arr[j];
                    arr[j] = arr[0];
                    arr[0] = temp;
                    //排好后仍有j个元素无序 如第一轮排完后只有一个元素有序,剩余arr.Length-1
                    //个元素无序,所以无序数组长度为j
                    //每次构造大顶堆都是从头开始构造的
                    adjustHeap(arr, 0, j);
                }
            }
            //将数组转换为大顶堆
            /// <summary>
            /// 将以i对应的非叶子结点的数调整为大顶堆
            /// </summary>
            /// <param name="arr">待调整的数组</param>
            /// <param name="i">非叶子结点的索引</param>
            /// <param name="length">多少个元素还是无序 length逐渐减少</param>
            public static void adjustHeap(int[] arr, int i, int length)
            {
                int temp = arr[i];//先取出当前元素的值
                //k=i*2+1是i结点的左子节点 k=i*2+2是i结点的右子结点
                for (int k = i * 2 + 1; k < length; k = k * 2 + 1)
                {
                    //k+1<length为了防止数组越界
                    if (k + 1 < length && arr[k] < arr[k + 1])//i的左子结点小于右子结点
                    {
                        k++;//k指向右子节点
                    }
                    if (arr[k] > temp)//子结点大于父结点
                    {
                        arr[i] = arr[k];
                        i = k;//让i指向k继续循环 i可以理解为用来跟踪本轮循环最小值的位置
                    }
                    else
                    {
                        break;//break的原因是从左到右,从下到上调整
                    }
                }
                //for循环结束后 已经将i为父结点的树的最大值放在了最顶上(局部大顶堆)
                arr[i] = temp;//将temp值放到调整后的位置
            }
  • 相关阅读:
    Linux bash sh .source exec 的区别比较。
    flink1.10 Linux 集群安装
    有关Spark中FlatMap算子源码理解
    Flink有关于水位线(WaterMark)相关问题
    Flink中并行度相关问题
    关于spark中的ResultStage和ShuffleMapStage
    关于windows10共享WiFi问题
    外网映射
    Druid的问题
    《小学四则运算练习软件软件需求说明》结对项目报告
  • 原文地址:https://www.cnblogs.com/TheLin/p/13913423.html
Copyright © 2020-2023  润新知