快速获取多个链表偏序的算法

标签 algorithm list linked-list

我有一个情况,如下:

  • 我有n个双向链表
  • 每个列表都有一个标记开始和结束
  • 所有列表都有相同的开始和结束节点(不是必需的,但为了简单起见)
  • 列表是同质的并且可以共享项目

我想找到所有 n 列表中所有节点的部分排序,从开始节点开始到结束节点结束,这样出现在 n 中的任何节点em>n-x 列表,其中 x < n,将根据它出现的所有列表中的其他节点进行排序。

使用数组提供一组示例列表:

first  = [a, b,    d,    f,    h, i];
second = [a, b, c,       f, g,    i];
third  = [a,          e, f, g, h, i];

显然,一个可能的答案是 [a, b, c, d, e, f, g, h, i],但另一种可接受的顺序是 [a, b, d, e, c, f, g , h, i].

我知道一个快速的算法可以做到这一点,有人记得它是怎么回事或者它叫什么吗?我已经有几个慢版本,但我确信在 Knuth 的某个地方有一个快得多的版本。

(而且,在你问之前,这不是作业或欧拉计划,我不能再具体了。这是问题所在。)

编辑:我相对确定只要端点位于所有列表中且位置相同(开始和结束),就可以定义偏序。我不反对通过线性时间搜索来找到这些端点,如果找不到它们,就会在那里引发错误。

最佳答案

看起来与 Topological sort 非常相似大部头书。有几种算法可以让您获得拓扑排序的状态。我特别喜欢的一个类似于广度优先搜索。维护两个列表,其中一个是没有边的所有节点,例如 L(最初只是 a 节点),另一个是部分有序节点, F。现在在每一步,

pick a node from `L`, 
do some operations (explained later), 
and move the chosen node to the `F` list. 

在“做一些操作步骤”中,

choose all successors of the source node which have exactly one in-link add them to L.
Remove the link from the source node to all the successors in the previous step 

现在,列表 F 对所有节点进行了拓扑排序。对于糟糕的解释,我很抱歉,维基链接有很好的图表:)

关于快速获取多个链表偏序的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6390205/

相关文章:

algorithm - 理解算法的时间复杂度

html - 尝试在无序列表中 float div

c - 向链表中插入一个元素

sql - 根据用户数据显示相关歌曲

在序列中查找元素 ai 的算法

python - 替换列表中的重复项目,同时保留第一次出现的项目

java - 提取 ArrayList<String> 的元素作为 Hashmap 的一部分

exception-handling - 尝试删除第一个对象时,如何在 Smalltalk 中捕获空的 LinkedList 异常?

c++ - 无法在 Main.cpp 中使用链表

algorithm - O(N) 或 O(2N) 哪个算法更快?