排序学习笔记(3) - 交换排序,堆排序

  学习排序,参考代码、测试程序:
http://tech.ddvip.com/2006-12/116513859112852.html
表示一下感谢~~

 

 

交换排序。

不稳定排序,性能:O(n*lg(n));

1)直接选择排序,一个值和所有的其他值比较;比较N次
2)锦标赛排序,没看,据说额外存储空间太大;

3)堆排序
原理:联想到最大堆的建立,建立之后最大值就出现了,这个时间是O(n*lg(n))。交换掉最大值之后,在建立一次的时间是O(lg(n)),n个元素全部重新建立一遍,就是O(n*lg(n)),所以时间上非常让人满意。所以应用到排序上,如果想从小到大排序,那么建立大堆。

代码:
建立堆,从倒数n/2个建立起,逐次向前面增加个数,直到建立完成全部n个;
排序的时候,刨除最大的之后(把最大个的和最后的元素对调),重新建立前面n-1个;逐渐刨除m个最大,重建前面n-m个,直到把整个堆都完成为止。

  1. template <class T>
  2. void FilterDown(T a[], int i, int N)
  3. {
  4.     int child = 2 * i + 1; 
  5.     T temp = a[i];
  6.     while (child < N)
  7.     {
  8.         if (child < N - 1 && a[child] < a[child+1]) 
  9.             child++;
  10.         if ( temp >= a[child]) 
  11.             break;//不需调整,结束调整
  12.         a[i] = a[child]; 
  13.         i = child; 
  14.         child = 2 * i + 1;
  15.     }
  16.     a[i] = temp;
  17. }
  18. template <class T>
  19. void HeapSort(T a[], int N)
  20. {
  21.     int i;
  22.     for (i = (N - 2)/2; i >= 0; i--)
  23.         FilterDown<T>(a, i, N); //生成最大堆
  24.     for (i = N - 1; i > 0; i--)
  25.     {
  26.         swap(a[0], a[i]); 
  27.         FilterDown(a, 0, i);    // 从小到大排序
  28.     }
  29. }

后记:

堆排序的整体性能非常不错,附加储存1,还没有很糟的情况,如果实在不放心快排的最坏情况,堆排确实是个好选择。

 

你可能感兴趣的:(排序学习笔记(3) - 交换排序,堆排序)