堆排序

来源:互联网 发布:剑三儒风盾太脸型数据 编辑:程序博客网 时间:2024/06/02 02:04
http://blog.csdn.net/shuilan0066/article/details/8659235 

选择排序算法,是选择最值,然后将其调整到合适位置。

如何确定最值,则是选择排序算法的关键。

 

简单排序算法是通过比较,确定最值的位置。假设未排序元素个数为N,则遍历一趟,需比较N-1次,再遍历下一趟时,需比较N-2次。但是,第二趟比较完全是独立的,没有利用第一次比较的信息。因为,第一趟比较时也没有把比较信息保留下来。

能不能找到一种方法,可以将本趟比较信息记录下来,以供下一趟求最值时使用,从而达到减少比较次数的目的。

 

一维数组,从直观上来看,是一种线性结构,这也是我们所熟知的。

但是,一维数组,还可以表达完全二叉树结构,这个确是不经常用到。


 


简单选择排序,是将一维数组看做线性结构,逐个比较。

但是,如果将其看做二叉树结构,有没有方法将其比较次数降低呢,于是便有了堆排序算法。

堆排序正是利用一维数组可表示完全二叉树,从而借助完全二叉树的性质来保存比较信息。从而达到减少比较次数的算法。

 

 

1.1定义

     n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质):
     (1) ki≤K2i且ki≤K2i+1或(2)Ki≥K2i且ki≥K2i+1(1≤i≤ )

 

若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。


 


1.2建堆方法




1.3建堆时间复杂度



1.4建堆算法

[cpp] view plaincopy
  1. //调整节点 大根堆  
  2. template<class T>  
  3. void AdjustHeapNode(T a[],int i,int n){ //调整节点i,数组共有N个节点  
  4.   
  5.   
  6.     if (n==1||i>(n-2)/2)  //i为叶子节点  (n-2)/2 最后一个非叶子节点的位置  
  7.         return;  
  8.   
  9.     int iLeft=2*i+1;  
  10.     int iRight=2*i+2;  
  11.   
  12.   
  13.     if (iRight<=n-1)     //说明i有左右两个子节点         三个节点找最大值  
  14.     {  
  15.         if (a[i]>=a[iLeft]&&a[i]>=a[iRight])      // i 最大 不用调整  
  16.             return;  
  17.   
  18.         if (a[i]<a[iLeft]&&a[iRight]<=a[iLeft])  // iLeft 最大  
  19.         {  
  20.             T temp=a[iLeft];  
  21.             a[iLeft]=a[i];  
  22.             a[i]=temp;  
  23.             AdjustHeapNode(a,iLeft,n);  
  24.             return;  
  25.         }  
  26.   
  27.         if (a[i]<a[iRight]&&a[iLeft]<=a[iRight]) // iRight 最大  
  28.         {  
  29.             T temp=a[iRight];  
  30.             a[iRight]=a[i];  
  31.             a[i]=temp;  
  32.   
  33.             AdjustHeapNode(a,iRight,n);  
  34.             return;  
  35.         }  
  36.   
  37.     }else// 说明i只有左节点   二个节点找最大值  
  38.   
  39.         //iLeft为最后一个节点  
  40.   
  41.   
  42.         if (a[i]>=a[iLeft])  
  43.             return;  
  44.         else  
  45.         {  
  46.             T temp=a[iLeft];  
  47.             a[iLeft]=a[i];  
  48.             a[i]=temp;  
  49.             AdjustHeapNode(a,iLeft,n);  
  50.             return;  
  51.         }  
  52.   
  53.     }  
  54. }  
  55.   
  56.   
  57. //建立堆  
  58. template<class T>  
  59. void CreateHeap(T a[],int n)  
  60. {  
  61.   
  62.     int iFirst=(n-1)/2; //第一个非叶子节点  
  63.   
  64.     for (;iFirst>=0;iFirst--)  
  65.     {  
  66.         AdjustHeapNode(a,iFirst,n);  
  67.     }  
  68.   
  69.   
  70. }  
  71.   
  72. //堆排序  
  73. template<class T>  
  74. void HeapSort(T a[],int n)  
  75. {  
  76.   
  77.     CreateHeap(a,n);  
  78.   
  79.     T temp;  
  80.     for (int i=0;i<n-1;i++)  
  81.     {  
  82.         temp=a[n-1-i];  
  83.         a[n-1-i]=a[0];  
  84.         a[0]=temp;  
  85.   
  86.         AdjustHeapNode(a,0,n-1-i);  
  87.     }  
  88.   
  89. }  

1.5堆插入





1.6 删除堆顶后调整



1.7 堆的意义





0 0
原创粉丝点击