Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 从(n log^2 n)到(n log n)时间的最近对算法_Algorithm_Sorting_Recursion_Closest Points - Fatal编程技术网

Algorithm 从(n log^2 n)到(n log n)时间的最近对算法

Algorithm 从(n log^2 n)到(n log n)时间的最近对算法,algorithm,sorting,recursion,closest-points,Algorithm,Sorting,Recursion,Closest Points,我试图理解如何从n log^2 n time转换到n log n time,以实现壁橱对算法。我得到下面的部分(来自) 用线l将集合分成两个大小相等的部分,并递归计算每个部分的最小距离 设d为两个最小距离中的最小值 消除距离l大于d的点 根据其y坐标对其余点进行排序 按y顺序扫描其余点,并计算每个点到其五个相邻点的距离 如果其中任何距离小于d,则更新d 步骤4是一个需要O(n logn)时间的排序,它支配着所有其他步骤,这是一个需要减少到O(n)的排序,以便整个算法实现O(n logn)时间。这

我试图理解如何从n log^2 n time转换到n log n time,以实现壁橱对算法。我得到下面的部分(来自)

  • 用线l将集合分成两个大小相等的部分,并递归计算每个部分的最小距离
  • 设d为两个最小距离中的最小值
  • 消除距离l大于d的点
  • 根据其y坐标对其余点进行排序
  • 按y顺序扫描其余点,并计算每个点到其五个相邻点的距离
  • 如果其中任何距离小于d,则更新d
  • 步骤4是一个需要O(n logn)时间的排序,它支配着所有其他步骤,这是一个需要减少到O(n)的排序,以便整个算法实现O(n logn)时间。这是我很难理解的部分。作者建议

    步骤1:将集合划分为…,递归计算每个部分的距离,按y坐标顺序返回每个集合中的点。 步骤4:在O(n)时间内将两个排序列表合并为一个排序列表


    在递归步骤中,仍然必须按y坐标对点进行排序,这需要O(n logn)时间。我们如何避免这种情况?合并是O(n),但我们仍然需要在某个地方进行排序

    他们的建议是,您有两个(已排序的列表)A和B。可以使用(步骤(4)中的东西作为合并排序中的合并步骤)将它们合并到一个已排序的列表中

    合并排序的结果是一个包含A和B的所有成员的已排序列表。一旦合并,就不需要再对任何内容进行排序。

    O(nlogn)是一个问题的原因是我们一次又一次地进行排序:如果我们将集合划分为两个子集,并将其中的每一个子集划分为两个子集,那么这涉及七种排序(一套一套,一半两套,四分之一套四套)


    所以这个建议通过重用以前的排序结果来解决这个问题:我们对最小的分区进行完全合并排序(每个分区都是O(1),总共是O(n)),但是对于较大的分区,我们只需要执行一个O(n)合并过程来合并这些结果。所以我们只需支付O(nlogn)总共定价一次,这很好。

    我提供了一个可能更容易理解的替代解决方案。首先,使用y坐标对所有点进行排序。这是一次使用O(n log n)。有n个点,在排序的数组中,每个点都有一些索引,最多为n。保存每个点的索引(为索引到点的数据结构添加整数)。然后运行原始算法。这次,在我们要对点进行排序的时刻,不要使用普通的比较排序对它们进行排序。而是根据它们的索引进行排序。我们可以使用O(n)中的基数排序根据它们的索引进行排序。因此,总的过程是O(n log n),因为我们只使用了一次比较排序,其余的是T(n)=2T(n/2)+O(n)。但常数不如问题中建议的修改好


    问题中建议的修改过程类似于合并排序中的合并:当我们有两个已排序的列表时,我们不需要使用普通排序对它们进行再次排序,我们可以通过在O(n)中合并它们来对它们进行排序.

    在原始问题中,我们有两个排序列表,但它们是根据x坐标排序的。我们如何合并它们而不首先按y坐标排序?或者你是说我们应该根据y坐标排序的点列表找出哪些是d?我只解释了如何修改这部分在O(n)中工作:“根据其y坐标对剩余的点进行排序”。其余的按原样排序。正如我所解释的,这提高了复杂性。我不太明白我们是如何对列表A和B进行排序的。我们首先按点的x坐标对列表进行排序,然后将其分成两个相等的部分,但这些部分按x坐标排序。我们需要什么第四步是按y坐标排序。我似乎遗漏了一些东西。谢谢-这个解释很有帮助,而且非常简洁明了。