堆排序:大堆排序就是将最大的数先进行排序,然后对剩下依次排序,自到堆里无未排序数据为止,
小堆排序,恰好相反, 用二叉树进行实现,
具体代码如下:
、
package com.qdcz.breadth.demo;
/** * * <p>Title: HeapA</p> * <p>Description:堆排序实现类 * 堆积排序(Heapsort)是指利用堆积树(堆)这种资料结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。堆排序是不稳定的排序方法,辅助空间为O(1), 最坏时间复杂度为O(nlog2n) ,堆排序的堆序的平均性能较接近于最坏性能。 </br> * 堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单 </br> * 用大根堆排序的基本思想: * 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区 </br> * 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key </br> * 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆 </br> * 直到无序区只有一个元素为止。 </br> * 大根堆排序算法的基本操作: * 初始化操作:将R[1..n]构造为初始堆; </br> * 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。 </br> * 注意: * 只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。 </br> * 用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。 </br> * <a href="http://blog.csdn.net/apei830/article/details/6584645">借鉴的资料</a> * </p> * <p>Company:奇点创智 </p> * <p>Version:1.0 </p> * @author Administrator * @date 2017年6月6日 下午4:05:26 */public class HeapA { public static void main(String[] args) { int[] data={13,2,12,42,4,43,34,1}; print(data); heapSort(data); System.out.println("排序后的数组:"); print(data); }
private static void heapSort(int[] data) { for (int i = 0; i < data.length; i++) { createMaxHeap(data,data.length-1-i); swap(data,0,data.length-1-i); print(data); } }
/** * *<p>Title: swap</p> *<p>Description: </p> *@param data *@param i *@param j *@return void *@author Administrator *@date 2017年6月6日 下午4:33:10 */ private static void swap(int[] data, int i, int j) { if(i==j)return; data[i]=data[i]+data[j]; data[j]=data[i]-data[j]; data[i]=data[i]-data[j]; }
/** * *<p>Title: createMaxHeap</p> *<p>Description:堆排序核心算法方法 </p> *@param data *@param lastIndex *@return void *@author Administrator *@date 2017年6月6日 下午4:32:29 */ private static void createMaxHeap(int[] data, int lastIndex) { for (int i = (lastIndex-1)/2; i >=0; i--) {//保存当前正在判断的节点 int k=i; //若当前节点的子节点存在, while(2*k+1<=lastIndex){ //bigger总是记录较大节点的值,先赋值为当前判断节点的左子节点 int bigger=2*k+1; if(bigger<lastIndex){ //若子节点存在,否则此时bigger应该等于lastIndex if(data[bigger]<data[bigger+1])bigger++; // 若右子节点值比左子节点值大,则bigger记录的是右子节点的值 } if(data[k]<data[bigger]){ // 若当前节点值比子节点最大值小,则交换2者得值,交换后将biggerIndex值赋值给k swap(data,k,bigger); k=bigger; }else break; } } }
private static void print(int[] data) { for (int i = 0; i < data.length; i++) { System.out.print(data[i]+"\t"); } System.out.println(); }
}
转载于:https://www.cnblogs.com/1x-zfd50/p/6958815.html
相关资源:JAVA上百实例源码以及开源项目