您的位置:首页 > 其它

堆排序分析

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/7172258
        2、堆排序的最坏时间复杂度为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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息