排序算法之:堆排序

堆排序(Heapsort)是指利用堆这种资料结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。

堆排序(HeapSort)是一树形选择排序。堆排序的特点是:在排序过程中,将集合看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(或最小)的记录

看实现:

/** * 堆排序 * */ public class HeapSorter { public void sort(Integer[] array, int from, int len) { build_heap(array,from,len); for(int i=0;i<len;i++) { //把最大的跟置换到最后面 swap(array,from,from+len-1-i); shift_down(array,from,len-1-i,0);//始终从根节点开始置换,最大的上升到根节点,小的下沉到叶子节点 } } //转换数组的两项 private void swap(Integer[] array,int x,int y) { Integer temp = array[x]; array[x]=array[y] ; array[y]=temp; } private final void build_heap(Integer[] array, int from, int len) { int pos=(len-1)/2;//从第一个非叶子节点开始 for(int i=pos;i>=0;i--) { shift_down(array,from,len,i); } } //把所有的非叶子节点同子节点比较 第pos个元素 选择与子节点中最大的元素与该节点置换 private final void shift_down(Integer[] array,int from, int len, int pos){ //暂时保存该节点的值, 因为这里可能不只进行一次比较 Integer tmp=array[from+pos]; int index=pos*2+1;//得到当前pos节点的左节点 while(index<len)//还存在左节点 { if(index+1<len&&array[from+index].compareTo(array[from+index+1])<0)//如果存在右节点 则比较 { //如果右边节点比左边节点大 index+=1; } //因为下面是单向赋值,所以这里要用tmp进行比较 if(tmp.compareTo(array[from+index])<0){ //注意这里是单向赋值,少了一次置换,当前值已经赋给tmp array[from+pos]=array[from+index]; //进行了置换操作后,以置换的子节点为起点 (如果存在子节点) 还要继续进行该操作 pos=index; index=pos*2+1; }else{ break; } } //最终全部置换完毕后 才把临时变量赋给最后的节点 array[from+pos]=tmp; } // 打印数组 public void printArray(Integer[] a) { System.out.println(); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); if ((i + 1) % 5 == 0) { } } System.out.println(); } public static void main(String[] args) { Integer[] a = { 45, 26, 13, 27, 35, 10, -455, -90, 2008, 1024, 101, 555, 216, 82 }; HeapSorter aa = new HeapSorter(); aa.sort(a, 0, a.length); aa.printArray(a); } }

算法分析

  堆[排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。  

堆排序的最坏时间复杂度为O(nlog2n) 。堆序的平均性能较接近于最坏性能。   

由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。   

堆排序是就地排序,辅助空间为O(1),   

它是不稳定 的排序方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值