V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zeal7s
V2EX  ›  程序员

问个关于排序的面试题

  •  
  •   zeal7s · 2015-10-19 11:56:01 +08:00 · 3196 次点击
    这是一个创建于 3327 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上周面试的时候被问了一道对单链表使用归并排序,我的解法是这样的:

    1. 通过快慢指针将链表一分为二
    2. 递归调用排序算法分别对两个链表进行排序
    3. 将两个排好序的链表合二为一

    以下是我的代码
    https://gist.github.com/fxxz/058689f7ecfb4633755b

    结果面试官不满意我的解法,他说没必要遍历链表的一半来取得链表中点,这样效率不是最高的。如果我没记错的话,他的做法大概描述如下:

    排序第一个 Node ,发现已排序,就归并前两个 Node 。已排好前两个 Node ,接着递归排第 3 和第 4 个 Node 。然后递归排第 1 , 2 , 3 , 4 个 Node 。这时候应该递归地把第 1 , 2 , 3 , 4 个 Node 和第 5 , 6 , 7 , 8 个 Node 归并,但是 5 , 6 , 7 , 8 还没排好,应该一层层递归下去把 5 , 6 , 7 , 8 个 Node 排列好。以此类推,直到链表末尾。

    听完面试官的做法,楼主有一种豁然开朗的赶脚,但是水平有限,实在写不出这样的归并排序。求问各位 V 友代码应该肿么写? THX

    13 条回复    2015-10-21 07:37:44 +08:00
    moro
        1
    moro  
       2015-10-19 13:42:24 +08:00
    gamingcat1234
        2
    gamingcat1234  
       2015-10-19 13:57:39 +08:00   ❤️ 1
    我觉得可以使用非递归的 merge sort ?
    可以参考 http://stackoverflow.com/questions/7685/merge-sort-a-linked-list 里面 ShitalShah 的回答。
    他说了下面这些,好像很符合你的要求。
    "Lot of other code on Internet and StackOverflow is horribly bad. There are people trying to get middle point of the list, doing recursion, having multiple loops for left over nodes, maintaining counts of ton of things - ALL of which is unnecessary."
    iShao
        3
    iShao  
       2015-10-19 14:02:57 +08:00 via Android
    看说明很像插入排序,也不需要递归
    iShao
        4
    iShao  
       2015-10-19 14:09:09 +08:00 via Android
    @gamingcat1234
    我手机上打开 stackoverflow 变成蓝色了,以前的屎黄色啥时候改版了?
    canesten
        5
    canesten  
       2015-10-19 16:20:40 +08:00
    这是面的哪家?
    linux40
        6
    linux40  
       2015-10-19 19:58:17 +08:00
    这个就是递归调用执行的过程啊。。。
    linux40
        7
    linux40  
       2015-10-19 20:00:04 +08:00
    @linux40 这才不是什么插入
    Aksura
        8
    Aksura  
       2015-10-19 20:03:06 +08:00
    @linux40 看描述确实是归并排序自顶向下递归的执行路径,但是看 @gamingcat1234 提到的那个帖子里的回答,也比较像,难道是题主 @zeal7s 听面试官说的时候理解有偏差?
    linux40
        9
    linux40  
       2015-10-20 09:50:11 +08:00 via Android
    @Aksura 那个贴子的最高票也是找中间指针,别的没看了。。。
    Aksura
        10
    Aksura  
       2015-10-20 11:18:46 +08:00
    @linux40 那个帖子里的 “ ShitalShah ” 的回答(不是最高票的)中的代码是可行的,执行顺序类似题主 @zeal7s 的描述,但是不是用递归。
    linux40
        11
    linux40  
       2015-10-20 13:04:11 +08:00
    @Aksura 本来就可以不用递归啊,先一个一个为一对地排,再两个两个为一对地排,再四个四个为一对地排。。。
    zeal7s
        12
    zeal7s  
    OP
       2015-10-20 22:47:58 +08:00
    @linux40 赶脚用递归是为了使代码更容易理解。。。
    linux40
        13
    linux40  
       2015-10-21 07:37:44 +08:00 via Android
    @zeal7s 写着方便也是一个原因。。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5539 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 07:58 · PVG 15:58 · LAX 23:58 · JFK 02:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.