一.为什么需要学习排序?
上学的时候学习排序是为了考试,是为了不挂科,在实际问题中,排序就显得不是那么重要了。特别是当使用c++ STL时,排序就是非常简单的事情了。
但为什么还需要学习排序呢?我个人感觉是为了理解细想,培养能力的一个必不可少的过程,像标题所提示的3个排序算法一样,特别是其中的分治算法对解决一切其他很多问题有深远的影响。
二.排序的用处.
排序是为了什么,在我接触的问题中,第一是为了显示,在游戏中必不可少,第二是为了多次查找。
比如说一个散列的数组需要查找一次,那么就直接遍历吧。最悲剧的情况,复杂度为O(n).
如果需要查找多次的话,那么排序后查找肯定要好的多。比如我们下面提到的分治排序,算法复杂度为O(n*ln(n)),如果再使用2分查找的话,复杂度为 O(ln(n)).如果有n个数,要使用K次查找的话,那么总的复杂度为O(n*ln(n) + K*ln(n))。使用直接遍历的话,那么复杂度为O(K * n).
从上面可以看出,当n或者K大于一个数的时候,排序后查找肯定速度要快得多。
三.实现排序
1.单元排序
讨论:
(1).每次排序完都把最小的排在前面,越到后面需要循环比较的次数越少;
(2).返回交换的次数,为了方便跟冒泡排序法比较;
(3).算法复杂度 O(n^2)
2.冒泡排序
讨论:
(1).每次完都把最小的放在前面
(2).返回交换的次数,为了方便跟选择排序法比较
(3).算法复杂度O(n^2)
3.分治排序
讨论:
(1).把一个大的问题分成相同类型小的问题处理后,在组合起来
(2).大部分的交换都变成2个元素之间的交换,大大减少的循环的次数
(3).算法复杂度 O(n*ln(n))
附加上交换的代码:
四.总结:
1.单元排序和冒泡排序的比较:
(1).算法复杂度都一样。
(2).冒泡排序的交换次数远远大于选择排序,所以不建议使用冒泡排序,我也很少看到有人使用冒泡排序。除了教科书上,因为最直接。
2.分治排序提高了很高的效率,但是实现起来也相对困难,不是那么直接。这也许就是对我这种执着的人有很大的魅力。有时候为了提高一点效率,硬是付出了很多的时间。哈哈~~~
3.关于分治排序的合并算法,当我写出后,去网上看看其他人写的,发现就我用了一个循环实现,有点感慨,也许N人都不把代码放出来,或者搜索引擎没搜到,反正至少满足了我一点荣誉感,对于程序原来说,也许就够了。
4.我不赞成使用自己写的排序,包括我自己写的我也不会使用,只是为了研究一个问题,得到一种思维,甚至可以说得到一点满足感。如果需要在问题中使用到算法,我绝不犹豫的把现有的问题映射到已经写好的算法中 ,比如说使用c++ STL。既安全,有省事,何乐而不为呢?
PS:因水平有限,不免有什么不妥之处,请各大看官不吝赐教,谢谢~