相对于第一列对第二列进行排序

时间:2013-10-10 08:39:55

标签: algorithm sorting

我有以下序列(代表一棵树):

4 2
1 4
3 4
5 4
2 7
0 7
6 0

现在,我正在尝试对此序列进行排序,这样当左侧(第1列)出现值时,它已经出现在右侧(第2列)。更具体地说,排序算法的结果应该是:

1 4
3 4
5 4
4 2
2 7
6 0
0 7

显然,这在O(n ^ 2)中工作,算法迭代第1列的每个条目,然后在第2列中查找相应的条目。但是因为在我的场景中n可能非常大(> 100000),我正在寻找一种O(n log n)方法来做到这一点。这甚至可能吗?

1 个答案:

答案 0 :(得分:2)

<强>假设:

我假设这也是一个有效的排序序列:

1 4
4 2
3 4
5 4
2 7
6 0
0 7

即。一旦值出现在右侧,它就会出现在左侧。

如果不是这种情况(即右边的所有出现都必须在左边的任何出现之前),忽略“删除指向该元素的所有边”部分,只有在没有传入的情况下才删除中间元素边缘留下。

<强>算法:

构造一个图形,其中每个元素A指向另一个元素B,如果A的右元素等于B的左元素。这可以使用哈希多图来完成:

  • 浏览元素,将每个元素A插入哈希映射中A.left -> A
  • 再次浏览元素,将每个元素BB.right下显示的所有元素相关联。

执行图表的topological sort,为您提供结果。我应该修改,以便不是删除指向元素的边,而是删除指向该元素的所有边(即如果我们已经在右边找到了包含某个元素的元素,我们不需要为此找到另一个元素元素出现在左边。)

目前这是O(n 2 )运行时间,因为边缘太多 - 如果我们有:

(1,2),(1,2),...,(1,2),(2,3),(2,3),...,(2,3)

有O(n 2 )边缘。

这可以通过以下方式避免,而不是让元素直接指向彼此,而是创建一个中间元素。在上面的例子中,1/2元素将指向该元素,该元素将指向另一半。然后,在进行拓扑排序时,当我们删除该元素的边时,我们会删除该元素以及指向/的所有边。

现在最多有O(n)个边,并且由于拓扑排序可以在相对于元素和边的线性时间内完成,因此整体运行时间为O(n)。

请注意,并非总能获得结果:(1,2), (2,1)

<强>插图:

对于您的示例(预优化),我们有:

对于我上面的例子,我们有: