选择排序和冒泡排序就该踢出教材?

bluewanderer 2010-12-01 04:22:59
至于这两个该踢出教材之说,姑且认为只是为了吸引眼球... 我只知道不少工作了几年的人给他讲那些O(N * logN)的算法都弄得我想跳楼,学校老师也不容易。

说说这两个算法的地位。

1. 选择排序是无法取代的。目前我不知道也没人跟我说过有什么排序算法逻辑比选择排序更简单。逻辑简单意味着代码量少,代码量少意味着单次循环执行速度就快。

logN有个特点:log512 = 9, log256 = 8, ..., log16 = 4, log8 = 3, log4 = 2, log2 = 1。也就是N越小logN和N越接近。8开始logN和N的关系基本上就是1:2了。而这个时候,对于很多比较压力小的排序,选择排序一次循环花的时间已经不到O(N * logN)算法的一半了。

所以其实真正使用快速排序或者合并排序的时候,往往会处理成当前的子序列短到一定程度的时候就切换成选择排序。

2. 冒泡也许的确是鸡肋算法,包括直接变体鸡尾酒算法,至少我还没碰上过什么加上冒泡算法比较好的情况。不过,除了鸡尾酒,冒泡排序还有一种至关重要的变体——堆排序。

总之,不能太小看简单的算法。
...全文
429 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
G_Spider 2010-12-10
  • 打赏
  • 举报
回复
算法复杂度不能完全决定程序执行的效率,还有许多细节要注意,包括Cache miss ,TLB miss等等技术问题。
总之,既要考虑计算速度,更要考虑存储层次。
super_admi 2010-12-02
  • 打赏
  • 举报
回复
我比较喜欢选择排序。主要是通用性强,逻辑简单,不容易出错。

如果有特别的速度瓶颈,我才会考虑去寻找更好的排序算法。
willabc 2010-12-02
  • 打赏
  • 举报
回复
楼主写的不错,经典的算法还是需要看看的!
yui 2010-12-02
  • 打赏
  • 举报
回复
6楼说得很好,顶一下

不过并不是gap为k,就是以k为底的,这个我也不懂,但是梳子排序中,1.3是一个实验值,gap取1.3通常比取2快
mschj 2010-12-02
  • 打赏
  • 举报
回复
能不能说的更详细些
bobo364 2010-12-02
  • 打赏
  • 举报
回复
接分,水平烂,我写的项目里只用冒泡排序
失落的凡凡 2010-12-02
  • 打赏
  • 举报
回复
头一次看到“鸡尾酒排序”,google一下看了看实现原理, 发现很适合用来排序基本有序的数据。刚好前一段时间还遇到过这种情况,不过数据量也不大。
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 pro_to_life 的回复:]
LZ说:逻辑简单意味着代码量少,代码量少意味着单次循环执行速度就快。

这样说不尽对吧,执行速度取决于时间复杂度。在说逻辑简单,也不定代码量少
[/Quote]

为什么我感觉我想说的就是执行速度不总是取决于时间复杂度呢...

反过来说代码就是描述逻辑的,代码多也就是逻辑的内容就多,也就是逻辑复杂...
pro_To_Life 2010-12-02
  • 打赏
  • 举报
回复
LZ说:逻辑简单意味着代码量少,代码量少意味着单次循环执行速度就快。

这样说不尽对吧,执行速度取决于时间复杂度。在说逻辑简单,也不定代码量少
do__i 2010-12-02
  • 打赏
  • 举报
回复
LZ话多,我喜欢!
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
“comb不是严格意义上的O(NlogN)”这个有问题,查了一气最后也糊涂了。基本上O(NlogN)这个说法本身就是个大概齐... 堆排序这样的是O(N * log2(N)),以2为底的logN。comb的gap缩减就是那个底。大体上这种gap以k等比递减的comb的复杂度精确说是O(N * logk(I) + N * (N - I))这么一个诡异状态,当k取1.3的时候,刚好I = N - 1或者N,所以后半部分忽略,结果就是O(N * log1.3(N))。

另外貌似comb最有解是个非等比数列的,不过wikipedia上没深入说...
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
当然数据不能太大,数据大了任何一次只移动一格的算法全都得玩完T.T
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 milkylove 的回复:]
头一次看到“鸡尾酒排序”,google一下看了看实现原理, 发现很适合用来排序基本有序的数据。刚好前一段时间还遇到过这种情况,不过数据量也不大。
[/Quote]

只是不完整地想了下,感觉对于基本有序的数据最有效的可能还是插入。其实至少对于已经基本拍好的数据插入排序如果不加二分查找的话和鸡尾酒的过程及其类似。
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yui 的回复:]
6楼说得很好,顶一下

不过并不是gap为k,就是以k为底的,这个我也不懂,但是梳子排序中,1.3是一个实验值,gap取1.3通常比取2快
[/Quote]

“gap以k等比递减”TvT,说comb是数学问题就是因为和shell一样,gap的取法非常tricky(诡异?一时想不出能对上的中文x.x?)2所以比1.3慢,就是1.3最多重复一次Θ(N)的循环,2可能重复很多次Θ(N)。也就是我说的这个,gap等比递减的话,comb的时间复杂度可以写成O(N * logk(I) + N * (N - I)),k取1.3,N - I不大于1,所以就可以看成O(N * logk(N))。k取2的话N - I很大,虽然前面logk的部分执行快了,但是最后遗留了需要O(N * (N - I))的尾巴。

comb和shell的核心其实都是移动速度(gap取法),移动快了就容易遗漏,遗漏就会加重后面O(N * (N - I))的负担,移动慢了有没效率。这种事只能由数学家搞。
  • 打赏
  • 举报
回复
一个帖子不能说明全部问题
两位作者,都说得有道理,而且不相冲突

原先一贴,让大家更多的对比与认识。
此贴让我们明白"韩寒虽然牛x,但不能取笑老一辈"





super_admi 2010-12-02
  • 打赏
  • 举报
回复
我写程序的时候,感觉在设计上越接近生活逻辑--而不是计算机逻辑,则代码维护起来就越容易。

对象就是一个最好的例子。一个对象,对应了生活中一个具体的事物,大家操纵起来就很舒服。
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
其实,个人感觉所有常规排序算法里最高深的就是shell和comb。其他排序算法都是逻辑问题,只有这两个是数学问题x_xb

comb不是严格意义上的O(NlogN),因为log的底不是2,所以很难界定,而且肯定比真正的O(NlogN)算法慢。英文wikipedia上就把comb归在O(N^2)里,当然应该也不严格,只能说是把所有gap取法都算上才是O(N^2)。

另外quicksort严格说是个O(N^2),因为O的定义是是复杂度不大于那个,quicksort显然只能满足总是小于O(N^2)的复杂度。不过quicksort和其他真正的O(NlogN)算法比还是有一定优势,不过这个很大程度上不是算法范畴的问题了。
yui 2010-12-01
  • 打赏
  • 举报
回复
O(n*n)算法和O(n*logn)算法都值得学习,O(n*n)算法通常是O(n*logn)算法的基础,易懂,代码简短,但并不意味着O(n*logn)算法就是高深的和复杂的,比如梳子排序算法也是O(n*logn)的,但是代码量不多于O(n*n)的选择排序和冒泡排序,而且也很容易理解,只不过是不稳定的排序。

http://blog.csdn.net/yui/archive/2010/10/21/5957264.aspx
失落的凡凡 2010-12-01
  • 打赏
  • 举报
回复
潜力贴。我这样做是不是太水了?啊……我知道错了……神啊……楼主啊……原谅我吧。
失落的凡凡 2010-12-01
  • 打赏
  • 举报
回复
楼主说的很好。再占一个。

69,368

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧