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

    /*
    堆是一棵完全二叉树,底层可以用数组实现,若根节点的index是0,那么若一个节点的index是i,它的父节点的index就是(i-1)/2,
    左右子节点的index是i*2+1和i*2+2。
    若是升序排列,就存储为最大堆,即任意节点都要比它的子节点要大。降序则存储为最小堆。
    步骤:
    1.构建最大堆,构建最大堆和每次调整最大堆都是把数组中最大元素调整到树顶
    2.顶元素和最后元素交换,相当于把顶元素排除
    3.调用adjust函数调整堆以还原为最大堆(此时不考虑已经排除的元素),重复步骤2,3直到结束
    
    构建最大堆:
    从最后一个非叶子节点(下标从0开始的情况下index是(n-2)/2)开始调用adjust函数,从下往上调整
    
     */
    
    public class Main {
    
        public static void main(String[] args) {
            int[] data = new int[]{2,8,4,3,1,6,9,7,10,-2,65};
            Main main = new Main();
            main.heapSort(data);
            for (int i = 0; i < data.length; i++) {
                System.out.println(data[i]);
            }
        }
        //堆排序主函数
        public void heapSort(int[] data)
        {
            if (data == null || data.length <= 1)
                return;
            //记录当前heap的size
            int heapSize = data.length;
            //1.构建最大堆函数
            //从最后一个非叶子节点开始
            int index = (heapSize-2)/2;
            for (int i = index; i >=0 ; i--) {
                adjust(i,heapSize,data);
            }
            //2.交换最后元素和顶元素(相当于取出顶元素(最大)到最后)
            while (heapSize > 1)
            {
                change(0,heapSize-1,data);
                heapSize--;
                //3.调整堆
                adjust(0,heapSize,data);
            }
    
    
        }
    
        //调整最大堆函数
        public void adjust(int index,int heapSize,int[] data){
            //左右子节点的index
            int left = index*2+1;
            int right = index*2+2;
            //记录此次比较的三个节点中最大的节点的index
            int biggest = index;
            //判断左子节点是否存在且是否比当前最大值大
            if (left < heapSize && data[left] > data[biggest])
            {
                biggest = left;
            }
            //判断右子节点是否存在且是否比当前最大值大,注意这里都是和biggest,不是index.因为是找出最大值,出错过一次
            if (right < heapSize && data[right] > data[biggest])
            {
                biggest = right;
            }
            //判断最大值的index是否还是当前节点index,不是的话:交换,递归,是的话(本来就是最大或者这是个叶节点)就会返回
            if (biggest != index)
            {
                change(index,biggest,data);
                adjust(biggest,heapSize,data);
            }
        }
        //交换函数
        public void change(int index1,int index2,int[] data)
        {
            int temp = data[index1];
            data[index1] = data[index2];
            data[index2] = temp;
        }
    }
  • 相关阅读:
    Mybatis框架学习02
    第四周学习进度
    第四周安卓开发学习总结(2)
    第四周安卓开发学习总结(1)
    使用Python进行疫情数据爬取
    使用Jsoup进行疫情数据爬取
    Mybatis框架学习01
    第三周学习进度
    第三周安卓开发学习总结
    全国疫情统计地图可视化(2)——实现数据下钻
  • 原文地址:https://www.cnblogs.com/stAr-1/p/7569706.html
Copyright © 2011-2022 走看看