博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
堆排序(java实现)
阅读量:6947 次
发布时间:2019-06-27

本文共 3112 字,大约阅读时间需要 10 分钟。

堆排序就是用大根堆或者小根堆的节点都比左孩子 右孩子大(小)的特性  来构建有序序列。

名词解释:

大根堆:所有节点(n)都比他的左孩子(2n+1)与右孩子(2n+2)大的完全二叉树。

小根堆:所有节点(n)都比他的左孩子(2n+1)与右孩子(2n+2)小的完全二叉树。

完全二叉树:深度为n的完全二叉树,在1到n-1层数上 节点的个数符合2^(n-1)。最后一程的节点,倒数第二层的节点,如果有有右孩子,则必有左孩子,如果下一个节点有孩子,则前一个节点必然有孩子。

堆排序首先建立一个大根堆(小根堆),然后根节点(root)的数与最后一个数(last)互换,现在本来在last的位置的数  跑到了根节点,本来在根节点的数(最大或者最小的)   跑到了最后面,然后再忽略最后面一个数,前面n-1个数再建立大根堆(小根堆)。以上过程一直循环。

代码摘自堆排序算法的百度百科:http://baike.baidu.com/link?url=ZyTlSiNFb4nLqDu7A3Slr9Xw90J3sFHFcq5QTZq9gQxaU5ZTpx2oh79QtSSJZJT5

package com.example;public class Test {    private static int[] sort = new int[]{1,0,10,20,3,5,6,4,9,8,12,17,34,11};    public static void main(String[] args) {        buildMaxHeapify(sort);        heapSort(sort);        print(sort);    }      private static void buildMaxHeapify(int[] data){        //没有子节点的才需要创建最大堆,从最后一个的父节点开始        int startIndex = getParentIndex(data.length - 1);        //从尾端开始创建最大堆,每次都是正确的堆        for (int i = startIndex; i >= 0; i--) {            maxHeapify(data, data.length, i);        }    }      /**    * 创建最大堆    * @param data    * @param heapSize 需要创建最大堆的大小,一般在sort的时候用到,因为最多值放在末尾,末尾就不再归入最大堆了    * @param index 当前需要创建最大堆的位置    */    private static void maxHeapify(int[] data, int heapSize, int index){        // 当前点与左右子节点比较        int left = getChildLeftIndex(index);        int right = getChildRightIndex(index);          int largest = index;        if (left < heapSize && data[index] < data[left]) {            largest = left;        }        if (right < heapSize && data[largest] < data[right]) {            largest = right;        }        //得到最大值后可能需要交换,如果交换了,其子节点可能就不是最大堆了,需要重新调整        if (largest != index) {            int temp = data[index];            data[index] = data[largest];            data[largest] = temp;            maxHeapify(data, heapSize, largest);        }    }      /**    * 排序,最大值放在末尾,data虽然是最大堆,在排序后就成了递增的    * @param data    */    private static void heapSort(int[] data){        //末尾与头交换,交换后调整最大堆        for (int i = data.length - 1; i > 0; i--) {            int temp = data[0];            data[0] = data[i];            data[i] = temp;            maxHeapify(data, i, 0);        }    }      /**    * 父节点位置    * @param current    * @return    */    private static int getParentIndex(int current){        return (current - 1) >> 1;    }      /**    * 左子节点position 注意括号,加法优先级更高    * @param current    * @return    */    private static int getChildLeftIndex(int current){        return (current << 1) + 1;    }      /**    * 右子节点position    * @param current    * @return    */    private static int getChildRightIndex(int current){        return (current << 1) + 2;    }      private static void print(int[] data){        int pre = -2;        for (int i = 0; i < data.length; i++) {            if (pre < (int)getLog(i+1)) {                pre = (int)getLog(i+1);                System.out.println();            }             System.out.print(data[i] + " ");        }    }      /**    * 以2为底的对数    * @param param    * @return    */    private static double getLog(double param){        return Math.log(param)/Math.log(2);    }}

 

转载于:https://www.cnblogs.com/hithlb/p/3599427.html

你可能感兴趣的文章
LeetCode手记-Add Binary
查看>>
对DNSPOD添加域名解析的一些见解
查看>>
vim添加删除多行注释
查看>>
在caffe中增加和convolution相同的层
查看>>
Java设计模式(四) 装饰 代理模式
查看>>
Filter过滤非法字符
查看>>
嵌入式系统烧写uboot/bootloader/kernel的一般方法
查看>>
PyCharm4注册码--软件安装
查看>>
【转】物业管理与移动互联网科技|微信公众平台,物业app,物业O2O
查看>>
patch与diff的恩怨
查看>>
蓝桥杯——先进的多说好树遍历
查看>>
Hdu 5444 Elven Postman dfs
查看>>
Nagios显示器MySQL一个错误:NRPE: Unable to read output具体的解决过程
查看>>
精讲母函数
查看>>
读取数据库中timestamp类型去掉毫秒
查看>>
(四)左右ng-app自己主动bootstrap相框
查看>>
九度OJ 1068 球半径和数量 (模拟)
查看>>
了解如何高速嵌入式?
查看>>
HDU4960Another OCD Patient(间隙dp,后座DP)
查看>>
Spark on Yarn遇到的问题及解决思路
查看>>