堆排序分析

来源:互联网 发布:淘宝上的图片怎么截图 编辑:程序博客网 时间:2024/05/04 07:50

堆排序分析

一、“堆”定义

  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[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].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

原创粉丝点击