学习排序,参考代码、测试程序:
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个,直到把整个堆都完成为止。
- template <class T>
- void FilterDown(T a[], int i, int N)
- {
- int child = 2 * i + 1;
- T temp = a[i];
- while (child < N)
- {
- if (child < N - 1 && a[child] < a[child+1])
- child++;
- if ( temp >= a[child])
- break;//不需调整,结束调整
- a[i] = a[child];
- i = child;
- child = 2 * i + 1;
- }
- a[i] = temp;
- }
- template <class T>
- void HeapSort(T a[], int N)
- {
- int i;
- for (i = (N - 2)/2; i >= 0; i--)
- FilterDown<T>(a, i, N); //生成最大堆
- for (i = N - 1; i > 0; i--)
- {
- swap(a[0], a[i]);
- FilterDown(a, 0, i); // 从小到大排序
- }
- }
后记:
堆排序的整体性能非常不错,附加储存1,还没有很糟的情况,如果实在不放心快排的最坏情况,堆排确实是个好选择。