【问题标题】:Sorting sets of ordered linked lists对有序链表集进行排序
【发布时间】:2010-09-14 19:06:24
【问题描述】:
我正在寻找一个优雅、高性能的解决方案来解决以下问题。
有 256 个链表。
- 每个列表都包含相同类型的对象,其中包含用于定义排序顺序的整数。
- 所有列表中的所有数字都是唯一的
- 每个单独的列表都按这些数字升序排序
如何从 256 个原始链表中的所有对象创建一个升序列表?我不想强行使用它,并有一些其他想法,但这似乎是有标准的最佳解决方案的问题之一。
【问题讨论】:
标签:
language-agnostic
sorting
linked-list
【解决方案1】:
您没有说这些列表有多长,但我假设它们都同时适合 RAM。我会尝试的第一件事是将它们全部附加在一起,并调用我的环境的内置排序例程,我会看看这是否提供了可接受的性能。它很容易实现并且不需要很长时间来测试。如果这不能提供可接受的性能,我会选择 Konrad Rudolph 给出的优先级队列合并。
【解决方案2】:
只需将每个列表与其上方的列表 128 合并即可。 (产生 128 个列表)
然后将每个列表与上面的列表 64 合并。 (产生 64 个列表)
然后将每个列表与上面的列表 32 合并。 (产生 32 个列表)
然后将每个列表与上面的列表 16 合并。 (产生 16 个列表)
然后将每个列表与上面的列表 8 合并。 (产生 8 个列表)
然后将每个列表与上面的列表 4 合并。 (产生 4 个列表)
然后将每个列表与上面的列表 2 合并。 (产生 2 个列表)
然后将每个列表与其上方的列表 1 合并。 (产生 1 个列表)
(您可以为上述使用循环)。
【解决方案3】:
如果单个列表已经排序,那么它是merge algorithm 的直接应用。简而言之:比较所有头并选择最小的,将其从列表中取出并推入您的输出列表。重复直到所有源列表都为空。
编辑:Konrad 使用优先级队列 (heap) 是一种更加优雅和可扩展的解决方案,但也许 256 个输入列表太少了,简单的比较可能会更快。
【解决方案4】:
您可以使用优先级队列来保存 256 个链表中每个链表的“最顶层”项。这个“最顶层”的项目是计划插入到结果列表中的项目。这样,您可以从优先级队列中取出最小的元素,将其插入结果队列,然后将其下一个元素插入优先级队列:
# Preprocessing:
result = list.new()
queue = priority_queue.new()
foreach (list in lists):
queue.push(list.first())
# Main loop:
while (not queue.empty()):
node = queue.pop()
result.insert(node)
if (node.next() != null):
queue.push(node.next())