Algorithm 通过用另一个函数替换其中一个递归来优化排序算法
目前我有这个排序算法:Algorithm 通过用另一个函数替换其中一个递归来优化排序算法,algorithm,sorting,complexity-theory,Algorithm,Sorting,Complexity Theory,目前我有这个排序算法: public static void sort(int[] A, int i, int j) { if (i == j) return; if(j == i+1) { if(A[i] > A[j]) { int temp = A[i]; A[i] = A[j]; A[j] = temp; } } else { in
public static void sort(int[] A, int i, int j) {
if (i == j) return;
if(j == i+1) {
if(A[i] > A[j]) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
else {
int k = (int) Math.floor((j-i+1)/3);
sort(A,i, j-k);
sort(A,i+k, j);
sort(A,i,j-k);
}
}
但是,它的排序正确,渐近比较非常高:T(n)=3T(n-f(n/3))和f(n)=θ(n^(log(3/2)3)
因此,我目前正在考虑替换第三个递归
sort(A,I,j-k)
使用一种新编写的迭代方法来优化算法。但是,我不确定如何解决这个问题,我很想收集一些想法。谢谢!如果我理解正确,你首先对列表的前2/3进行排序,然后对最后2/3进行排序,然后再对前2/3进行排序。这实际上是可行的,因为任何错误都放错了位置项目(第一个或最后2/3中实际属于最后一个或前1/3的项目)将被移位,然后在算法的下一个过程中正确排序
当然有两点可以优化:
- 在最后一步中,前1/3和后1/3(以及要排序的区域的前半部分和后半部分)已按排序顺序排列,因此,您可以使用合并算法,而不是进行完全排序,该算法应以O(n)运行
- 如前所述,您可以对前1/2和后1/2进行排序,然后合并这些部分,而不是对第一个和最后一个2/3进行排序,然后将重叠中的元素合并到第一个1/3中。处理的数组的总长度相同(2/3+2/3+2/3与1/2+1/2+2/2),但合并部分将比排序部分快
然而,在第二次“优化”之后事实上,你或多或少会被重新发明。我检查了代码,它正在工作。因此,如果我读对了,你将列表的前2/3排序,然后是最后的2/3,然后是前2/3。不确定这是否真的总是有效,或者如何有效,但你肯定会对列表的6/3进行排序。难怪这会比较慢。@tobias_k,所以我希望通过用新方法替换第三个递归来优化算法。在第2步中,前半部分已经被排序,在最后一步中,前半部分和后半部分都被排序,因此您可以在这里使用合并算法,而不是完全排序。如果您进一步考虑,您可以对第一个和第二个ha进行排序如果没有重叠,然后将它们合并,从而重新发明……你可能想在你的问题上补充一句,这是一个众所周知的“坏”调用了排序算法。它可能会为不确定是否有效的人添加一些上下文。我明白了!但是,由于只有数组的第一个和最后一个1/3被排序,而第二个1/3没有被排序,我如何将两个已排序和一个未排序的数组合并到一个数组中?我需要在合并方法中实现某种排序吗?@CSnewbie No,f或者合并两个“一半”要合并的区域的1/2必须进行内部排序。请注意,在第二次优化中,我建议对第一个和最后一个1/2进行排序,而不是1/3。如果不允许修改代码的其余部分,但只允许修改最后一个递归调用,那么合并是否仍然有效?是的,因为您正在合并内部排序的第一个1/3和第二个1/3。