堆排序

转载自:http://blog.csdn.net/caimo/article/details/7783970

堆是一个完全二叉树的数组对象。树每一层都是满的,最后一层可能除外(从一个节点的左子树开始填)。



给定节点 i ,可以很容易计算父节点和子节点的位置。


Parent(i) =floor(i/2)   :i/2再向下取整


LeftChild(i) =2*(i+1)-1   :因为i从0开始,这和c语言的数组从0开始相对应。可以用左移运算代替*,即LeftChild(i)=(i+1)<<1 - 1;


RightChild(i) = 2*(i+1)   :RightChild(i) = (i+1)<<1;



堆排序


堆排序的时间复杂度是O(nlgn),是比较有效率的一种。其使用的是最大堆。最大堆的意思是父节点的值>=孩子的值。那么第0个节点必定是该堆的最大值。所以,堆排序的思想就是每次循环把最大值移走,然后从剩下的节点重新建立最大堆。


第一步:建立堆的结构体。


  1. typedef struct heap_t{  
  2.     int *arr;          //point for an array to store heap value.  
  3.     int heapMaxIndex;   //heap element max index number  
  4.     int arrLength;  //array length of arr  
  5.       
  6. }Heap;  

其中arr指针指向的是存放堆数据的数组。


heapMaxIndex是数组最大的序号。如数组定义为a[10],那么heapMaxIndex的值应该为9.


 


第二步:保持堆的性质。


这一步是堆排序的基础。这里将功能写成一个函数名为void maxHeapify(Heap *hp, unsigned int nodei),这个函数用于让一个数组变成一个符合堆性质的数组。时间复杂度为O(h),h是堆所属二叉树树的高度=lgn(n是节点个数)。


思想是:从一个节点i,和他的孩子leftchild(i),rightChild(i)中找到最大的,然后其索引存放在largest中。如果i是最大的。那么i为根的子树已经是最大堆,程序结束。


否则i的某个子节点有最大元素,那么i的值和largest的值交换。下标为largest的节点在交换后作为父节点,那么他可能又违反堆性质,因此递归调用该函数。


 


  1. void maxHeapify(Heap *hp, unsigned int nodei)  
  2. {  
  3.     unsigned int l = (nodei+1) << 1 - 1;  //left child = 2i-1, -1 ?:arr[0..n-1]  
  4.     unsigned int r = (nodei+1) << 1 ; // right child = 2i  
  5.     unsigned int largest = 0;  
  6.     int heapMaxI = hp->heapMaxIndex;  
  7.   
  8.     if(l <= heapMaxI && hp->arr[l] > hp->arr[nodei])  
  9.         largest = l ;  
  10.     else  
  11.         largest = nodei ;  
  12.       
  13.     if(r <= heapMaxI && hp->arr[r] > hp->arr[largest])  
  14.         largest = r ;  
  15.   
  16.     if(largest!=nodei)  
  17.     {     
  18.         //exchange   
  19.         int tmp ;  
  20.         tmp = hp->arr[largest];  
  21.         hp->arr[largest] = hp->arr[nodei];  
  22.         hp->arr[nodei] = tmp;  
  23.           
  24.         maxHeapify(hp,largest);  
  25.     }else{  
  26.         return ;  
  27.     }  
  28.       
  29. }  

 

 

 

posted on 2015-11-17 08:55  雨渐渐  阅读(151)  评论(0编辑  收藏  举报

导航