Mergesort递推公式 - 将现实与教科书相协调

时间:2014-11-14 15:38:56

标签: algorithm big-o mergesort recurrence

我认为这比数学编程更多,所以我发布在这里。

我的问题中的所有Java算法都来自here

我们有一个迭代和递归合并排序。两者都使用相同的合并功能。

教授this教授说合并排序的关键操作是比较。

所以我根据比较结果为merge()提出了这个公式:

>3n + 2

3:最差情况通过每个循环进行比较。
n:循环次数的迭代次数 2:“测试”比较。

recursiveMergesort()具有基本情况比较加上总计的递归调用:

>T(n/2) + 1 + 3n + 2 = T(n/2) + 3n + 3

iterativeMergesort()只有一个循环,运行*n/2*次,运行 n 次的嵌套循环。这导致我采用这个公式(但我认为这是错误的):

>(n/2) * n + 3n + 2 = (n^2)/2 + 3n + 2

书中说递归mergesort的递推公式是

  

2T(n / 2)+ theta(n)

使用主方法解决

  

THETA(NlogN)

问题1: 我创建的公式如何简化为

  

T(n / 2)+ theta(n)

问题2: 我可以使用这些公式中的任何一个(我创建的公式,教科书公式或时间复杂度*theta(nlogn)*)来预测运行 此特定算法时的比较数 在数组大小 n

问题3: 奖金:迭代方法的公式是否正确?

合并:

private static void merge(int[] a, int[] aux, int lo, int mid, int hi) {
   // DK: add two tests to first verify "mid" and "hi" are in range
   if (mid >= a.length) return;
   if (hi > a.length) hi = a.length;
   int i = lo, j = mid;
   for (int k = lo; k < hi; k++) {
      if      (i == mid)     aux[k] = a[j++];
      else if (j == hi)      aux[k] = a[i++];
      else if (a[j] < a[i])  aux[k] = a[j++];
      else                   aux[k] = a[i++];
   }
   // copy back
   for (int k = lo; k < hi; k++)
      a[k] = aux[k];
}

递归合并排序:

public static void recursiveMergesort(int[] a, int[] aux, int lo, int hi) {
   // base case
   if (hi - lo <= 1) return;
   // sort each half, recursively
   int mid = lo + (hi - lo) / 2;
   recursiveMergesort(a, aux, lo, mid);
   recursiveMergesort(a, aux, mid, hi);
   // merge back together
   merge(a, aux, lo, mid, hi);
}

public static void recursiveMergesort(int[] a) {
    int n = a.length;
    int[] aux = new int[n];
    recursiveMergesort(a, aux, 0, n);
}

迭代合并排序:

public static void iterativeMergesort(int[] a) {
  int[] aux = new int[a.length];
  for (int blockSize=1; blockSize<a.length; blockSize*=2)
     for (int start=0; start<a.length; start+=2*blockSize)
        merge(a, aux, start, start+blockSize, start+2*blockSize);
   }
哇,你在这里一路走来。谢谢!

1 个答案:

答案 0 :(得分:4)

问题1:

你在哪里得到你的事实?要获得theta(nlogn)复杂性,您需要

T(n) = a T(n/b) + f(n), where a > 1, b > 1 and f(n) = cn + d. c != 0

注意:还有其他约束,由Master theorem

决定

您无法从基于T(n) > T(n/2) + 3n + 3的reccurence关系派生出来。您可能忘记了大小为n的数组的成本是合并的成本加上 两次 每个部分的成本。所以相反

  T(n) = 2T(n/2) + 3n + 3

问题2:

在阵列大小n上运行此特定算法时,不能使用theta,Big O或Big Omega来预测比较次数。因为它们是渐近表达式。假设它是正确的,你需要解决上面的关系。

例如T(n) = 2T(n/2) + 3n + 3 has the solution

T(n) = 3n log2(n) + 1/2(c+6)n - 3, c constant

这仍然是算法的比较次数。不考虑实际程序的所有优化和约束。

问题3: 都能跟得上