重新排序列表的元素,以便连续的元素相互成功?

时间:2012-02-16 10:39:18

标签: algorithm list sorting data-structures

给定大小为n的项目列表l,如果succeeds(i1,i2)成功i2,则谓词i1返回true,重新排列l的元素的最佳算法是什么对于我在l中的所有项目,succeeds(i,i.next)都返回true?

2 个答案:

答案 0 :(得分:4)

如果对成功关系没有任何限制(也就是说,它不必是传递关系,反身关系,对称等),那么我认为这个问题是通过从NP-hard Hamiltonian path problem 。减少实际上非常简单:给定图G,在图中创建一个具有成功关系的节点数组,这样如果在原始图中存在从u到v的边,则v成功。通过这种设置,找到一种通过成功关系(连接它们的边)对数组元素(节点)进行排序的方法等同于在原始图中找到哈密顿路径,因为每个节点只被访问一次。因此,除非P = NP,否则您不太可能找到有效的算法。

对于否定的结果感到抱歉,希望这会有所帮助!

答案 1 :(得分:2)

如果每个元素只有一个元素,那么这个问题可以在二次时解决。

它实际上是模仿从数据创建链接列表并将其作为数组返回。瓶颈在于找到每个元素 - 跟随它的元素。

的伪代码:

specialSort(array,n)
   create an array a of size n
   for each i from 0 to n:
      find j such that succeeds(array[i],array[j]) == true //this may require linear search, so it is O(n)
      if there is such j:
          a[i] = j
      else:
          a[i] = -1
   end for
   find i such that for any j: a[j] != i
   create empty result array of size n
   j = 0;
   while (i != -1):
      result[j++] = array[i]
      i = a[i]
   end while
   return result

如果对每个元素可以成功的元素数量没有限制,那么答案@templatrtypedef给你的是正确的,你的问题等同于找到哈密顿路径。

编辑:任何有序关系的问题都可以解决
请注意,如果每个元素可以有多个后继,但关系succeed()排序良好[no“loops”],则可以从此问题构建DAG [每个元素都是一个顶点,每个对都有一个边缘,succeed(a,b) == true],使用topological orderring - 然后返回它。
这也是二次时间,因为瓶颈正在寻找边缘。