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

    堆结构:是一个完全二叉树

    i的左右结点分别为2 * i + 1 和 2 * i + 2,

    父结点:(i - 1)>>1

    构建大根堆heapInsert:每次添加进来的结点 i 找到它的父结点(i-1)>>2,若大于父结点,则交换,继续寻找此时父结点的父结点  

    调整大根堆heapIfy:将交换后的结点与其两个子结点进行比较(若小于他们)则与较大的子结点进行交换,然后继续向下寻找


     如果只是建立堆的过程, 时间复杂度为O(N)
     优先级队列结构, 就是堆结构

    public void HeapSort(Integer[] arrays){
            if(arrays == null || arrays.length == 0) return;
    
            for(int i = 1; i < arrays.length; i++){
                //从0~i位置调整成大根堆
                heapInsert(arrays, i);
            }
            for(int j = arrays.length - 1; j > 0;){
                swap(arrays, 0, j);
                heapIfy(arrays, --j, 0);
            }
        }
    
        //将一个结点加到当前大根堆,并且调整位置的过程
        public void heapInsert(Integer[] arrays, int index){
            while(index > 0 && arrays[index] > arrays[(index - 1) >> 1]){
                swap(arrays, index, (index - 1) >> 1);
                index = (index - 1) >> 1;
            }
        }
    
        //数组中某位置index出的值变小了,调整成大根堆的过程
        public void heapIfy(Integer[] arrays, int len, int index){
            int left = index * 2 + 1;
            while(left < len){
                //右孩子不越界,且右孩子比左孩子大,则前边成立,否则后边成立
                int max = left + 1 < len && (arrays[left + 1] > arrays[left]) ? left + 1: left;
                
                //判断最大的孩子与父结点的值谁大谁小,若父结点的值大,则退出,否则交换,继续向下进行比较
                max = arrays[index] > arrays[max] ? index : max;
                if(max == index) break;
                swap(arrays, index, max);
                index = max;
                left = index * 2 + 1;
            }
        }
    

      

    重点是构造大顶堆(或小顶堆)

    在构造过程中,要知道一个规律:起始点为1 -- len的数组中,

    i的左右结点分别为2 * i + 1 和 2 * i + 2,

    而换算在以0开始的数组中,

    i处的左右结点分别为2 * i - 1和2 * i

    堆排序中,是将大顶堆的最前边的是arrays[0]从后往前依次进行替换,将大顶堆的数值依次交换到后面去

    而且在构造大顶堆的时候,是从len/2开始,它的左右子结点分别为 2 * i 和2 * i + 1,其实在数组中是2 * i - 1和2 * i

    package sort;
    import static sort.PrintRes.swap;
    public class HeapSort {
        public void heapSort(Integer[] arrays){
            if(arrays.length == 0) return;
            //构造大顶堆
            int len = arrays.length;
            for(int i = len - 1; i > 0; i--){
                bigHeap(arrays, len--);
                if(arrays[0] > arrays[i]){
                    swap(arrays, 0, i);
                }
            }
            //将大顶堆的数值与数组的最后一个数交换,继续构造大顶堆
        }
    
        public void bigHeap(Integer[] arrays, int len){
            for(int i = len/2; i >= 1; i--){
                int max;
                if(i * 2 >= len) max = i * 2 - 1;
                else{
                    max = arrays[i * 2 - 1] > arrays[i * 2] ? i * 2 : i * 2 + 1;
                }
                if(arrays[i - 1] < arrays[max - 1]) swap(arrays, i - 1, max - 1);
            }
        }
    }
    

      

     应用:剑指offer——最小的K个数

  • 相关阅读:
    python模块--time模块
    python模块--如何相互调用自己写的模块
    Animating Views Using Scenes and Transitions
    fragment 切换
    android textview 设置text 字体
    android intent 5.1
    android EditView ime
    animation of android (4)
    animation of android (3)
    animation of android (2)
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/8666570.html
Copyright © 2011-2022 走看看