HeapSort的java语言实现
2015-06-01 16:22
399 查看
堆排序的实现
思想如下
第一步:建堆(最大堆或最小堆)第二步:排序
要注意的是:建堆和排序的过程中都会进行堆的维护,以最大堆为例:节点的值不小于左右两个子节点(若存在)的值,也不大于父节点的值;若不满足这样的情况,则需要调整
java实现的代码如下:
package org.wrh.algorithmimplements; import java.util.Arrays; //堆排序的实现 /* * 堆排序需要两个步骤: * 第一:建堆 * 第二:排序 * 其中建堆和排序的过程中都需要维护堆的性质 * */ public class HeapSortImplement { public static void main(String[] args) { int []arr={9,8,7,4,6,5,4,9,3,1,8,0,2}; System.out.println("排序前的数组如下:"+Arrays.toString(arr)); //建堆 buildHeap(arr,arr.length); //排序 heapSort(arr,arr.length); System.out.println("排序后的数组如下:"+Arrays.toString(arr)); } /* * 完成对数组的排序 * 思想如下:因为我们采用的是最大堆,因此我们将一个元素与最后的一个元素交换,然后调用heapify来调整,就这样继续下去,直至结束 * */ private static void heapSort(int[] arr, int length) { int heap_size=length; while(heap_size>0){ heap_size--;//将堆的大小减一,使得将数组中的最后面已经排好序的在堆中隐藏掉 swap(arr,0,heap_size);//注意这里是下标为零的位置与最后的位置进行交换;容易写成“1” headify(arr,0,heap_size); } } /* * 此函数是将任意数组建成一个最大堆 * 建堆的要点在于:由于(n/2)+1到n的下标元素是堆的叶子节点,首先将这些叶子节点各看成一个单元素的堆,然后逐级往上面进行调整使其成为最大堆 * */ private static void buildHeap(int[] arr, int length) { for(int i=length/2-1;i>=0;i--){ //调用维护堆的函数 headify(arr,i,arr.length); } } /* * 当我们对堆进行改变之后,我们需要对堆进行调整,使其具有最大堆的性质,此函数就完成此功能 * */ private static void headify(int[] arr, int i,int heap_size) { //i位置的值可能不是最大值,而i位置的左孩子和右孩子还具有最大堆的性质,故需要调整 int left=2*i+1; int right=2*i+2; int largest; /* * 注意:首先要判断的是left和right是否在数组的边界之内;然后才比较出最大值进行交换,最后再维护最大堆性质 * */ if(left<heap_size&&arr[left]>arr[i]){ largest=left; } else { largest=i; } if(right<heap_size&&arr[right]>arr[largest]){ largest=right; } /* * 这里要注意的是:只有当i与largest不相等的时候,才交换,若相等则说明的是此时是满足最大堆性质的 * */ if(i!=largest){ swap(arr,i,largest); headify(arr,largest,heap_size); } } /* * 用来调整数组中两个位置的顺序 * */ private static void swap(int[] arr, int i, int largest) { if(i!=largest){ int temp=arr[i]; arr[i]=arr[largest]; arr[largest]=temp; } } }
代码中注释写的比较详细,这里就不在解释。
总结
堆排序的时间复杂度为:O(nlogn)堆排序与插入排序类似,都是原址排序
堆排序与归并排序在时间复杂度上一样,相比之下,快排要更好,因为快排是平均性能下的时间复杂度为O(nlogn)
相关文章推荐
- eclipse 下github 安装
- java数据类型杂记
- Java I/O系统----------- I/O流的典型使用方式
- Java I/O系统----------- 标准I/O
- win8 系统 myeclipse10.x 破解
- eclipse 工程手工配置
- java中如何定义不规则数组
- eclipse必备快捷键
- 好记性不如烂笔头88-spring3学习(9)-schema的配置的解读和说明
- 【JAVA教程】关于增强visualvm的一些想法
- Java I/O系统----------- 类图框架
- Vijava 学习笔记之CustomizationIdentification、 CustomizationUserData
- eclipse或IDEA连接魅蓝
- Eclipse 安装FindBugs插件
- IntelliJ IDEA 之 jdk Language level
- JAVA设计模式之单例模式
- Java垃圾回收机制
- eclipse SVN 安装
- Struts2配置详解_配置Action
- JDK的动态代理