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

    1、堆的特点
    • 是完全二叉树:除了树的最后一层结点不需要是满的,其他的每一层从左到右都完全是满的。
    • 通常采用数组实现
    • 堆中的每一个结点都满足堆的条件,也就是说每一个结点的关键字都大于等于(或小于等于)这个结点的子节点的关键字
    堆节点的访问:
         对于给定的某个结点的下标 i,
    • 它的父节点的下标为floor((i-1) / 2)
    • 它的左子节点的下标为2 * i + 1
    • 它的右子节点的下标为2 * i + 2

    堆排序算法思想

    将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将其与堆数组的末尾元素交换,此时末尾元素就是最大值,然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次最大值。如此反复执行,就能得到一个有序序列了。

    /**
     * 时间复杂度O(NLogN), 空间复杂度O(1)
     * @author Wu
     *
     */
    public class HeapSort {
        
        private static int[] arr = new int[]{1,0};
        public static void main(String[] args) {
            // 堆排
            heapSort(arr);
            // 打印排序后的数组
            print(arr);
        }
        
        private static void heapSort(int[] arr) {
            
            // 将待排序的序列构建成最大堆,从最后一个父节点开始
            for(int i = arr.length / 2 - 1; i >= 0; i--) {
                buildMaxHeapify(arr, i, arr.length);
            }
            
            // 逐步将每个最大值的根节点与末尾元素交换,并且再调整二叉树,使其成为大顶堆 
            for(int i = arr.length - 1; i >= 0; i--) {
                
                // 将堆顶记录和当前未经排序子序列的最后一个记录交换  
                int tmp = arr[0];  
                arr[0] = arr[i];  
                arr[i] = tmp;  
             
                buildMaxHeapify(arr, 0, i); // 交换之后,需要重新检查堆是否符合大顶堆,不符合则要调整  
            }
            
                    
        }
        /**
         * 构建最大堆过程
         * @param arr    原数组
         * @param i    根节点序号
         * @param length    数组长度
         */
        private static void buildMaxHeapify(int[] arr, int i, int length) {
            int largerChild;
            int top = arr[i];
            while(i < length / 2) {            // 只要i不在堆的最底层,也就是它只要至少还有一个子节点,就一直循环
                int leftChild = 2 * i + 1;
                int rightChild = 2 * i + 2;
                
                // 找最大的子节(要考虑右子节点不存在的情况)
                if(rightChild < length && arr[rightChild] > arr[leftChild]) {
                    largerChild = rightChild;
                } else {
                    largerChild = leftChild;
                }
                
                // 交换根节点与子节点,使满足最大堆
                
                if(top >= arr[largerChild]) {
                    break;
                }
                
                arr[i] = arr[largerChild];
                i = largerChild;
            }
            arr[i] = top;  
        }
        
        
        private static void print(int[] arr) {
            for(int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            
        }
    
        
        
        
    }
  • 相关阅读:
    Ubuntu Windows双系统时差8小时问题解决
    linux无线网络配置
    Ubuntu 10.04上腾达W541U V2.0 无线网卡驱动的使用
    有些歌,放在这慢慢听
    [推荐]什么是程序员的优秀品质?
    如何阅读源代码
    Ubuntu中的有线、无线网络连接管理器──Wicd[译]
    linux下无线网卡解决方案之Ndiswrapper终极使用指南
    将jar文件做成exe可运行文件
    WOW裁缝1375详细攻略
  • 原文地址:https://www.cnblogs.com/zywu/p/5936428.html
Copyright © 2011-2022 走看看