“如果数据是基本有序的(升序或降序,但无法知道是哪一种),这种情行下,基数排序则是最好的选择。”墨出尘道。
“那么什么是基数排序呢?”少女问道。
“所谓基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。”
“用听得懂的人话,翻译翻译。”
“还是举个栗子好了,还是原来的序列,3、44、38、6、47、15、36、26、27、2、46、4、19、50、48。”
先按个位数分别放到0-9的箱子里
0:50
1:
2:2,
3:3,
4:44,4
5:15,
6:6,36,26,46,
7:47,27,
8:38,48
9:19
按照个位数有小到大排列,为
50、2、3、44、4、15、6、36、26、46、47、27、38、48、19
再按十位数分别放到0-9的箱子里
0:2,3,4,6
1:15,19
2:26,27
3:36,38
4:44,46,47,48
5:50,
6:
7:
8:
9:
由于已经没有百位数,所以排序完毕,结果为
2、3、4、6、15、19、26、27、36、38、44、46、47、48、50
“是不是非常简单呢?这种排序就是先保证个位数的有序性,再保证十位数的有序性,不断下去……算法只需要归类,不需要比较。”
“那如果数据本身不但有序,而且已知是升序呢?”少女看来是打算追根究底了。
“那就是插入排序最快了,所谓的插入排序如下所示。”
从第一个元素开始,该元素可以认为已经被排序;取出下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置;重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;将新元素插入到该位置后,不断重复。
“举个栗子。”
依旧是针对3、44、38、6、47、15、36、26、27、2、46、4、19、50、48,过程如下:
3
3、44
3、38、44(寻找38需要插入的位置)
3、6、38、44(寻找6需要插入的位置)
3、6、38、44、47
3、6、15、38、44、47
3、6、15、36、38、44、47
3、6、15、26、36、38、44、47
3、6、15、26、27、36、38、44、47
2、3、6、15、26、27、36、38、44、47
2、3、6、15、26、27、36、38、44、46、47
2、3、4、6、15、26、27、36、38、44、46、47
2、3、4、6、15、19、26、27、36、38、44、46、47
2、3、4、6、15、19、26、27、36、38、44、46、47、48
2、3、4、6、15、19、26、27、36、38、44、46、47、48、50
“That's it。”
“假设有人给了你150,000万份纪录表,每张表上都记录着一个大学生的信息,要按年龄对其排序,你会怎么做?”看来少女是跟排序杠上了。
“这不就是把前面的排序问题套了个帽子吗,学生的年龄是随机的呀,自然还是快速排序大法。”墨出尘不加思索道。
“别,我觉着面试官不会蠢到把相同的问题问两遍的。”钟奇正也学会了面试官心理分析。
“或许是打一个反逻辑呢?”
“还是别把狼人杀套用到生活中了吧,谁吃饱了撑的!”
“我们要不求助一下面试官吧。”
“你们这种程序员、工程师号称聪明,其实还往往比不上一个不懂计算机为何物的老太太。
“我曾经问过我妈妈这个问题,当然她压根不懂计算机,她稍微想了一下,给出的方案就比你们所谓的快速排序好得多。她是这样说的:『我会先分堆,首先看看第一张纸上记录的年龄,如果是21岁,就把她放到21岁的堆里。如果下一张纸写着19岁,就把它放在19岁的堆里,以此类推。每张纸只需看一次,等完成之后,把各堆按年龄顺序收集起来,大功告成!』”
“Soga,我就说面试官不会重复她自己吗,刚那个是32位整数,范围很大,这道题是大学生年龄,总共就那么几种,这个时候就要用到计数排序了。”
”那这道题我们是算完成还是没完成啊?”
“这道题算你们完成,但没有拿到完美奖励分,得分6分。下一题,你有25匹马,需要多少场比赛才能找出跑得最快的三匹马?你没有秒表,由于场地限制,每次比赛只能让五匹马参赛。”
“事实上跑得最快,我认为是不存在的。”墨出尘道。
“为何不存在?”
“首先一匹马今天跑得最快不代表明天仍然跑得最快,这场跑得最快,不代表下场仍然跑得最快。另外,什么是最快呢?以三匹马为例子,有可能A跑得赢B,B跑得赢C,C跑得赢A,所以究竟谁最快呢?”
“我们假设马的实力是不变的,且>号可以传递,即如果A跑得赢B,而B又跑得赢C,那么A就跑得赢C。”
“这样还是不行,如果比赛存在平局,即A和B一样快,我怎么处理?”
“按照与成绩排名一样的规则,即如果两个人同分,可以并列第三名。”
“这样的话应该需要7场比赛。先5场比赛,25匹马分五组轮流上一遍,分出每组第一名。假设为A、E、H、S、U马。然后这五匹马赛一场,假设名次为A、E、H、S、U。那么第一是A无疑;接着A组的2、3名,E组的1、2名及H,这五匹马赛一场,其中的前两名就是总排名的2、3名。”
“回答正确,得三分,对于这种赛制你们有什么看法吗?”
“首先实际的比赛不会采用这种方式,因为前面的假设不成立,先以世界杯足球赛为例。”
32支参赛队通过抽签分为八个小组,每个小组分别有四支球队进行比赛,每支球队都必须和其他三支球队进行且只进行一场比赛,每组4个队循环比赛,共打6场,每场比赛90分钟,胜平负分别积3、1、0分。每个小组积分的前两名球队出线进入淘汰赛阶段的1/8决赛,共16支队,即“16强”。
接下来,
A组第一对阵B组第二=胜者1
A组第二对阵B组第一=胜者2
C组第一对阵D组第二=胜者3
C组第二对阵D组第一=胜者4
E组第一对阵F组第二=胜者5
E组第二对阵F组第一=胜者6
G组第一对阵H组第二=胜者7
G组第二对阵H组第一=胜者8
获胜的8个队进入1/4决赛,即所谓“8强”
1/4决赛
胜者1对阵胜者3=胜者A
胜者2对阵胜者4=胜者B
胜者5对阵胜者7=胜者C
胜者6对阵胜者8=胜者D
1/4决赛的4个获胜队进入“4强”
半决赛
胜者A对阵胜者C
胜者B对阵胜者D
决赛
半决赛获胜两队进入决赛,失利的两队争夺三名。这是足球赛,而与体育比赛不同,电子竞技通常会采用双败淘汰制。
以19年TI杯DOTA2为例,16支队分为1234四个组,每组有ABCD四支队,每组共有两支战队出线。每组第一轮比赛通过抽签决定对阵情况,假设1组对阵情况为A VS B,C VS D。接下来的赛程就是:
第一轮:A战胜了B,C战胜了D,那么A和C进入胜者组,B和D进入败者组;
第二轮:A和C进行胜者组比赛,B和D进行败者组比赛;假设A战胜C,B战胜D,则A作为胜者组冠军从小组出线,B晋级到败者组决赛,C因为输给A落入败者组,将与B争夺另一个出线名额;D则被直接淘汰。
第三轮:B和C通过败者组决赛决出最后一个晋级名额,这里设B战胜C,那么1组的晋级情况就是:A第一,B第二,C第三,D第四,从而AB晋级CD淘汰。
与双败赛制相对的自然就是单败赛制了,该赛制被普遍运用于各大传统体育项目中,比如NBA季后赛,可以说几乎所有的体育比赛都倾向于使用单败赛制,而各类电竞比赛(包括围棋比赛)则更愿意使用双败赛制。
首先,双败赛制相比单败赛制有一个明显的缺点:比赛进程太长,场次过多。对于足球篮球等比赛,如果采用双败赛制,对球员体能的要求将会变得非常高;另外足球篮球对场地、设备、人员等要求也很高,举办体育比赛所需要的成本远远高于电竞比赛,所以双败赛制并不适合传统体育项目。
其次也是最重要的一点,传统体育比赛受偶然因素影响比较小,很少会因为场外因素导致胜负结果颠倒,所以没必要采用受偶然因素影响较小的双败赛制;而电竞比赛的不确定因素相比传统体育项目要多很多,设备故障、网络卡顿等都有可能影响一场比赛胜负,且电竞比赛相比传统体育对体能、场地、人员等要求相对要低一些,所以电竞比赛更适合双败淘汰赛制。
但DOTA2波士顿和基辅特锦赛就采用过单败赛制,结果缔造了Ad Finem的希腊神话,所以单败赛制相比双败赛制更容易爆出冷门。