Algorithm 使用已排序和反向排序的替换元素对链接列表进行排序

Algorithm 使用已排序和反向排序的替换元素对链接列表进行排序,algorithm,sorting,data-structures,linked-list,Algorithm,Sorting,Data Structures,Linked List,我在一次采访中被问到这个问题 列表如下所示 a1->bn->a2->bn-1…->an->b1->NULL 这样,, a1

我在一次采访中被问到这个问题

列表如下所示

a1->bn->a2->bn-1…->an->b1->NULL

这样,, a1

b1 面试官对我提出了以下限制:

  • 您必须将列表排序到位,即您不允许 将一组图元中的备用图元删除到单独的 名单
  • 您必须以某种方式利用列表中的模式,而不是简单的排序算法
  • 我在面试时想不出解决办法,现在也是-(

    编辑:用C编写代码,对这个单链表进行排序

    Edit2:也有人告诉我,我可以借鉴bubble sort的一些想法,并利用这个模式。但它不应该是一个“幼稚”的短剧

    我讨厌面试官人为地施加限制,但嘿,工作就是工作:-)

    “你必须对清单进行适当的排序”这一要求让我感到困惑。我认为自然的解决方案是:

    • 通过抖动列表中的“下一个”指针,创建两个列表。一个包含a,另一个包含b,相反
    • 对这两个列表进行合并
    但我不确定第一步是否违反了规则。按照我的理解,它是“就地”的,因为它不复制节点或它们的数据,事实上它也不移动任何数据。但它确实将替代元素删除到一个单独的列表中

    我无法立即思考如何将这两个步骤合并为一个步骤

    [编辑:这里的“就地”可能意味着我们应该移动数据,而不是重新链接列表。在这种情况下,我认为问题更难:在数组中,高效就地合并排序已经够痛苦的了,而不需要尝试(a)在链接列表上进行排序,(b)以错误的顺序替换元素]

    以保持其“就地”,您可以首先将列表就地转换为

    a1->…->an->b1->…->bn

    通过遍历列表并将b元素逐个移动到列表的末尾

    在此之后,您可以以“气泡排序方式”逐个向前移动a元素,即向前扫描,直到找到它们位于边界之后的位置,该边界最初位于b1之前


    然而,我同意这个问题是相当人为的。

    那么,期望的结果是什么?将列表作为一个整体进行排序,而不区分
    a
    b
    元素?编辑该问题以解决以下问题:comments@Saurabh你还没有回答我的问题。期望的输出是什么?我有。这个问题已经得到了回答:你必须对列表进行排序,@Saurabh实际上,没有。你所说的只是列表应该“排序”。您还没有指定这是否意味着
    a
    b
    节点之间不应有区别。史蒂夫,这也是我对这个问题的第一反应,但根据采访者的说法,这是一项要求。@Saurabh:嗯,如果不允许重新链接节点,则链表就像没有随机访问的数组。因此,解决方案将与数组相同,但速度可能较慢。我认为这就是他的意思。我会接受你的回答。天哪,我现在很尴尬:我认为进一步的改进是首先对反向排序的替换元素进行排序。然后合并两个已排序的列表。@Saurabh:提到冒泡排序提醒我,冒泡排序是一种访问模式的最佳排序,在这种模式中,您可以通过一个小窗口查看内存,该窗口向前跟踪,但不向后跟踪,然后在开始时再次开始(旋转鼓存储)。单链表就是这样,向前移动很便宜,但向后移动必须从头开始。我还没有想到一种方法来优化这种输入数据思想的冒泡排序。