zoukankan      html  css  js  c++  java
  • 堆排序

          二叉堆的构建,删除节点以及自我调整等基础的操作是实现堆排序的基础(详看上一篇)。

          在最大堆中,如果删除了堆顶元素,然后经过自我调整后,第二大的元素就会被交换上来,称为最大堆的新堆顶。(在堆排序中的删除,并不是真正的删除,而是将其与完全二叉树最后的一个元素交换位置)。例如下图分析:

     对于上图,黑色节点为每次最大堆的堆顶与最末尾元素换下来的元素,红色节点为每次换完调整后的最大堆的最大值。

    从上可分析排序算法步骤:

    1. 先将无序数组构建成二叉堆,需要从小到大排序,构建最大堆;需要从大到小排序,则构建最小堆。
    2. 循环删除堆顶元素,替换到二叉堆的末尾,然后重新构建堆产生新的堆顶。

    具体实现:

    /**
    *将无序数组构建成二叉堆,所需要的时间复杂度是O(n),而每次交换完都需要重新调整构建,需要(n-1)logn,所以时间复杂度是    O(nlogn)。
    *
    */
    public class StackSort {
        public static void main(String[] args) {
            int[] array = new int[]{1,5,6,3,2,8,7,9};
    //        构建堆
            for (int i = (array.length - 2)/2; i >= 0; i--) {
                downAdjust(array,i,array.length);
            }
    //交换首节点和末尾节点
            for (int i = array.length - 1; i > 0; i--) {
                int tail = array[i];
                array[i] = array[0];
                array[0] = tail;
                downAdjust(array,0,i);  //重新调整堆
            }
            System.out.println(Arrays.toString(array));
        }
    
        /**
         * "下沉"节点构建大根堆
         * @param array   待调整数组
         * @param i       根结点
         * @param length  有效的位数
         */
        private static void downAdjust(int[] array, int i, int length) {
            int parentIndex = i;    //父节点下标
            int childIndex = 2*parentIndex+1;   //左孩子节点
            int temp = array[parentIndex];   //临时保存父节点的值
            while (childIndex < length){   //存在左孩子
    //            如果存在右孩子,并且右孩子比左孩子大的话,定位到右孩子
                if(childIndex+1 < length && array[childIndex+1] > array[childIndex]){
                    childIndex = childIndex+1;
                }
    //            如果父节点大于左右孩子中最大的,直接退出
                if(temp > array[childIndex]){
                    break;
                }
                //否则
                array[parentIndex] = array[childIndex];
                //每次比较都交换,好理解(相对于最终赋值)
                array[childIndex] = temp;
    //            更新结点
                parentIndex = childIndex;  //向下比较,大的上浮
                childIndex = 2*parentIndex+1;
            }
    //        最终赋值(不需要每次比较都交换,每次只是向下覆盖,只是最终实现赋值)--->推荐
    //        array[parentIndex] = temp;
        }
    
    }
  • 相关阅读:
    对Cost (%CPU) 粗略的理解
    SQL AND &amp; OR 运算符
    [Nagios] Error: Template &#39;timman&#39; specified in contact definition could not be not found (c
    质因数分解
    细数人体器官仿生,还有哪些可开发的
    利用京东云擎架设免费Wordpress 博客(git方式)
    C++内存管理变革(6):通用型垃圾回收器
    二分查找法
    百度云存储教程---免费建立自己的静态网站
    paip.提升效率---filter map reduce 的java 函数式编程实现
  • 原文地址:https://www.cnblogs.com/128-cdy/p/13412711.html
Copyright © 2011-2022 走看看