堆排序算法

转自 http://blog.csdn.net/pigli/article/details/5751772

堆排序(Heap Sort)是一种选择排序,每趟从待排序列中选出最大或者最小的关键字。

    首先来解释下什么叫堆?

    堆定义:n个元素的序列{k1,k2,…,kn}当且仅当满足下关系时,称之为堆。

    或其中。

    堆排序,也是对满足堆条件的序列的排序。那么对一个无序的序列进行堆排序之前,首先要将待排序序列转换成堆。如何将无序序列转换成堆?

    若将满足堆条件的序列看做是完全二叉树存储结构,那么这颗完全二叉树就满足以下条件:某根结点的值大于等于其左右子节点的值,或者根结点的值小于等于左右子节点值。根据这个特点,将无序序列转换成堆的思路就有了。即是:将不满足此条件的完全二叉树转换成满足此条件的完全二叉树。下面以根堆最大为例描述具体的实现方法。

    首先从第个元素开始,查看它是否大于等于左右子节点,若是则查看-1个元素;若不是则将这个元素与其左右结点中较大的元素进行互换。

    无序序列转换成了堆,那么如何对堆进行排序呢?

    堆排序是一种选择排序,也就是说每趟从数列中选择一个最大或者最小的元素。那么在堆中,根结点就是序列中最大或者最小的元素。那么对堆进行排序首先就是将序列的第一个元素也即是根结点元素与最后一个元素进行交换,序列长度减一。那么现在最后一个元素就称为了根结点元素,这必然打乱了原来的堆,那么就需要原有的堆进行重新排列,形成一个新的堆。查看新的根结点r是否大于等于其左右子节点,若不满足则与其中较大者m互换,互换了之后r是m的子结点,但是若此时的r还有子节点的话,还需要查看其是否大于等于其子节点

 

    注意:上述描述中讲到完全二叉树,并不是说明待排序的序列需要用二叉树的结构来存储。而是,将待排序的序列看成是一颗完全二叉树的顺序存储结构

 

具体实现代码:

 

[java] view plaincopy
 
  1. package Sort;  
  2. /* 
  3.  * 堆排序其实是利用了用数组表示完全二叉树的一个特点,那就是完全二叉树上某个节点的编号k,k*2和k*2+1是k节点 
  4.  * 的左右节点的编号 
  5.  * 堆排序有两个步骤:1。如何将一个无序序列建成一个堆序列 2。如何在输出堆顶元素之后调整剩余元素成为一个新的堆。 
  6.  */  
  7. public class HeapSort   
  8. {  
  9.     private int[] heapData;  
  10.     private int numberOfElement;  
  11.       
  12.     public HeapSort(int[] array)  
  13.     {  
  14.         heapData = new int[array.length+1];  
  15.         numberOfElement = array.length;  
  16.           
  17.         for(int i=0;i<array.length;i++)  
  18.         {  
  19.             heapData[i+1] = array[i];  
  20.         }  
  21.           
  22.     }  
  23.       
  24.     //将一个无序序列建立成一个堆序列  
  25.     public void buildHeapArray()  
  26.     {  
  27.         int start = numberOfElement/2;  
  28.         for(int j = start;j>0;j--)                                     
  29.         {  
  30.             int tmp_j = j;  
  31.             buileHeap(tmp_j,numberOfElement);  
  32.         }  
  33.     }  
  34.       
  35.     private void buileHeap(int tmp_j,int num)                                   //使某个元素的左右子树全部都是堆序列  
  36.     {  
  37.         //当结点元素与其子节点交换之后,仍需查看子节点与其子节点之间是否需要进行交换,所以要注意这里需用循环条件来控制                                                                    
  38.         while(tmp_j<=num/2)                                                       
  39.         {  
  40.             if(tmp_j*2+1>num)  
  41.             {  
  42.                 if(heapData[tmp_j]<heapData[2*tmp_j])  
  43.                 {  
  44.                     heapData[0] = heapData[tmp_j];  
  45.                     heapData[tmp_j] = heapData[2*tmp_j];  
  46.                     heapData[2*tmp_j] = heapData[0];  
  47.                     tmp_j =  2*tmp_j;  
  48.                 }  
  49.                 else  
  50.                     break;  
  51.             }  
  52.             else  
  53.             {  
  54.                 if(heapData[tmp_j*2]>heapData[tmp_j*2+1])  
  55.                 {  
  56.                     if(heapData[tmp_j]<heapData[2*tmp_j])  
  57.                     {  
  58.                         heapData[0] = heapData[tmp_j];  
  59.                         heapData[tmp_j] = heapData[2*tmp_j];  
  60.                         heapData[2*tmp_j] = heapData[0];  
  61.                         tmp_j =  2*tmp_j;  
  62.                     }  
  63.                     else  
  64.                         break;  
  65.                 }  
  66.                 else  
  67.                 {  
  68.                     if(heapData[tmp_j]<heapData[2*tmp_j+1])  
  69.                     {  
  70.                         heapData[0] = heapData[tmp_j];  
  71.                         heapData[tmp_j] = heapData[2*tmp_j+1];  
  72.                         heapData[2*tmp_j+1] = heapData[0];  
  73.                         tmp_j =  2*tmp_j+1;  
  74.                     }  
  75.                     else  
  76.                         break;  
  77.                 }  
  78.             }  
  79.         }  
  80.     }  
  81.       
  82.     public void sort()  
  83.     {  
  84.         buildHeapArray();  
  85.         for(int j=numberOfElement; j>0; )  
  86.         {  
  87.             heapData[0] = heapData[1];  
  88.             heapData[1] = heapData[j];  
  89.             heapData[j] = heapData[0];  
  90.             j--;  
  91.             if(j>0)  
  92.             {  
  93.                 buileHeap(1,j);  
  94.             }  
  95.         }  
  96.           
  97.     }  
  98.       
  99.     public void print()  
  100.     {  
  101.         for(int i=1;i<=numberOfElement;i++)  
  102.         {  
  103.             System.out.print(heapData[i]+"     ");  
  104.         }  
  105.     }  
  106.       
  107.     public static void main(String args[])  
  108.     {  
  109.         int[] array = {5,38,65,97,76,13,27,49};  
  110.         HeapSort heap = new HeapSort(array);  
  111.         heap.sort();  
  112.         heap.print();  
  113.     }  

 

 

posted @ 2014-06-13 02:14  princessd8251  阅读(348)  评论(0)    收藏  举报