堆排序分析
2012-04-09 16:19
162 查看
堆排序分析
一、“堆”定义
n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):(1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子 。
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
二、堆排序的基本思想
① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R
交换,由此得到新的无序区R[1..n-1]和有序区R
,且满足R[1..n-1].keys≤R
.key
③由于交换后新的根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]调整为堆。
……
直到无序区只有一个元素为止。
三、算法分析
1、构造堆时间复杂度为O(n)。证明参考:http://blog.csdn.net/linuxtiger/article/details/71722582、堆排序的最坏时间复杂度为O(nlogn)。堆序的平均性能较接近于最坏性能。
3、由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。
4、堆排序是就地排序,辅助空间为O(1),
5、它是不稳定的排序方法。
四、大根堆的实现
import java.util.Random; public class HeapSort { /** * * <p>Discription:调整堆,构造大根堆</p> */ public static void heapAdjust(int[] a, int pos, int length){ int child; int parent; for(parent = pos; (child = 2 * parent + 1) < length; parent = child){ //如果存在右孩子,且右孩子大于左孩子 if(child + 1 < length && a[child] < a[child + 1]){ child++; } //如果根节点关键字小于最大的孩子节点关键字,交换位置 if(a[parent] < a[child]){ int temp = a[parent]; a[parent] = a[child]; a[child] = temp; }else{ break; } } } /** * * <p>Discription:把数组变成堆</p> * @param a */ public static void toHeap(int[] a){ int len = a.length; for(int i = len / 2 -1; i >= 0; i--){ heapAdjust(a, i, len); } } /** * * <p>Discription:堆排序 </p> * @param a */ public static void heapSort(int[] a){ int len = a.length; while(len > 1){ int last = --len; //交换第一个元素与最后一个元素 int temp = a[0]; a[0] = a[last]; a[last] = temp; heapAdjust(a, 0, len); } } public static void main(String[] args){ int[] a = new int[]{0,1,2,3,4,5,6,0,1,2,3,4,5,6}; int len = 15000000; int[] b = new int[len]; Random rdm = new Random(System.currentTimeMillis()); for(int i = 0; i < len; i++){ b[i] = rdm.nextInt(100000000); } long beginTime = System.currentTimeMillis(); //把数组变成堆 toHeap(b); //堆排序 heapSort(b); long endTime = System.currentTimeMillis(); System.out.println(endTime - beginTime); } }
五、参考文献
1、堆排序:http://baike.baidu.com/view/157305.htm
相关文章推荐
- 对字符串进行直接插入排序、堆排序、归并排序、快速排序实现以及性能分析
- 堆排序及其分析
- 【算法分析】排序算法:希尔、归并、快速、堆排序
- 堆排序及其分析
- 堆排序分析及优化
- PHP堆排序实现与分析
- 冒泡排序、选择排序、堆排序、快速排序、插入排序算法复杂度分析与算法实现(自己总结与转)
- 简单排序算法时间空间复杂度分析及应用(5)-堆排序
- 关于堆排序中MAX-HEAPIFY中时间复杂度的分析
- 堆排序及其分析
- 【排序】插入排序,希尔排序,选择排序,冒泡排序,堆排序详解及稳定性分析
- 堆排序及其分析
- 快排 和 堆排序算法的细节代码分析
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 算法分析-选择排序(直接选择排序 & 堆排序)
- 算法分析:堆排序
- 插入排序与堆排序分析
- 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析(好戏在后面,有图有真相)
- 堆排序中--建堆的算法复杂度分析O(n)
- 堆排序详细分析(算法导论第六章)