美文网首页
选择排序---堆排序

选择排序---堆排序

作者: 水欣 | 来源:发表于2018-03-02 15:29 被阅读0次

    二叉堆的定义

    二叉堆是完全二叉树或者是近似完全二叉树。
    二叉堆满足两个特性:

    • 父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值
    • 每个节点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)
      当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。下图展示一个最小堆:


      11B3620D-3236-4882-89D8-0E45CDA8A62D.png

    堆的存储

    一般都用数组来表示堆,i节点的父节点下标为(i-1)/2。它的左右子节点下标分别为2i+1和2i+2。如第0个节点左右子节点下标分别为1和2.

    1A2BD5F2-D816-4846-A220-5C068D3C132C.png

    java代码

    public static void heapSort(int[] arr) {
            // 将待排序的序列构建成一个大顶堆
            for (int i = arr.length / 2; i >= 0; i--) {
                heapAdjust(arr, i, arr.length);
            }
    
            // 逐步将每个最大值的根节点与末尾元素交换,并且再调整二叉树,使其成为大顶堆
            for (int i = arr.length - 1; i > 0; i--) {
                swap(arr, 0, i); // 将堆顶记录和当前未经排序子序列的最后一个记录交换
                heapAdjust(arr, 0, i); // 交换之后,需要重新检查堆是否符合大顶堆,不符合则要调整
            }
        }
    
        /**
         * 构建堆的过程
         *
         * @param arr 需要排序的数组
         * @param i   需要构建堆的根节点的序号
         * @param n   数组的长度
         */
        private static void heapAdjust(int[] arr, int i, int n) {
            int currentIndex = i;
            while (currentIndex <= n / 2 - 1) {
                int leftChildIndex = currentIndex * 2 + 1;
                int maxChildIndex = leftChildIndex;
                if (leftChildIndex < n - 1) {
                    if (arr[leftChildIndex] < arr[leftChildIndex + 1]) {
                        maxChildIndex = leftChildIndex + 1;
                    }
                }
                if (arr[currentIndex] < arr[maxChildIndex]) {
                    int temp = arr[currentIndex];
                    arr[currentIndex] = arr[maxChildIndex];
                    arr[maxChildIndex] = temp;
                    currentIndex = maxChildIndex;
                } else {
                    break;
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:选择排序---堆排序

          本文链接:https://www.haomeiwen.com/subject/mrqbxftx.html