我认为这比数学编程更多,所以我发布在这里。
我的问题中的所有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);
}
哇,你在这里一路走来。谢谢!
答案 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: 都能跟得上