【发布时间】:2015-01-12 01:19:39
【问题描述】:
我认为这更像是编程而不是数学,所以我在这里发布。
我问题中的所有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
书上说递归归并排序的递归公式是
2T(n/2) + theta(n)
用master方法解决
θ(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);
}
哇,你一路走到这里。谢谢!
【问题讨论】:
-
书中对theta(N)的定义是什么?它与大 O 符号
O(n)有什么不同吗? -
我认为当他说比较是关键部分时,他并不是指比较索引,索引总是整数。考虑一个对象数组,其
compareTo()方法必须访问它们的所有字段。关键比较是实际元素比较。 -
@NoseKnowsAll:是的。 theta(n) 包括下限和上限。 O(n) 只是上限。
-
@RealSkeptic:那么
else if (a[j] < a[i])是唯一的关键操作吗?掉期(aux[k] = a[j++])呢?它们很重要吗?
标签: algorithm big-o mergesort recurrence