我们在打扑克的时候有两种策略,一种是一边抓牌一边排序,比如:抓到2,再抓到5就排在2的左边,又转到3就放到中间,如此递归,牌抓好了也排序好了,“似乎”很快。原因就是,在其他小伙伴抓牌的时候,你在排序,属于并行计算,可不是你的排序算法比较优秀,不过这种排序也是O(n)的时间复杂度,效率还是很高的。
而另一种策略就是大家先不排序,几个小伙伴拼命抓牌,每个人都抓好牌之后,大家集中“摆牌”,其实我小时候玩牌就是这种方法,而计算机的排序问题基本都是这种情况。你只有两只手,不能增加多一个手帮你,存储空间一定,那么你就排序吧。基本策略就是:从第二张开始看是否比第一张大,如果大就放到左边;然后看第三张,从最右边开始比较,如果比他小就放到他右边,否则就一路向上直到最左,所以这种复杂度是O(n*n)。经过我的实践证明,人家打出牌了之后,我还没有排序完成,这种方法真的很耗时,而这种方法就叫“插入排序”,其实我们每个人都会,好深奥的感觉似的。
上面是玩斗地主的排序,如果你玩升级就有新的玩法,把4种花色分组,然后再排序,如果还是先抓牌,再排序这样做,你就会发现,你的速度有明显提高,而这种“分治思想”就是算法的优化,把大问题转化成小问题,这种每个小问题都容易解决,整体就加速解决了。快速排序就是这个思路,不过我们玩升级采用的叫“桶式排序”,在上百万数据以上的大数据方面,比其他方式都快,当然是“让无序数据变有序”,而不是“在有序数据里面找数据”。
但是无论那种排序,先抓牌后排序的总是没有一边抓牌一边排序,插入过程就是排序过程,这样来得快。这种方法就是“B树”的存储结构,时间复杂度是O(log(n)),你有一个2到K的同花顺,然后你抓到了10,这时候你应该不会从2数到10这样,扇形握牌第一眼你会看到中间的8,然后从这里向左移动两位就是10了,插入进去再抓牌。这样你无形之中就少数了一半的牌,这样复杂度就从线性的O(N),变成对数曲线的O(log(n))。当然如果你是天才,能有3只手,把扑克牌分成3个区间,比如:1-5,2-10,J-K,抓牌时候你直接到对应的手里面去插入,多块啊,这就变成了“B-树”了。所谓的优化,也不过就是这样简单思路的扩展而已,其实我们每个人都会,只不过你不拿来写论文骗经费罢了,呵呵。