首先,我要声明这是一个家庭作业问题,我已经进行了大量的尝试。
我被要求修改 Java 中的快速排序,以使用公式将枢轴设置为数组中 9 个值的伪中位数i * (n-1) /8
我写了一个computeMedian
方法,它接受 3 个整数,确定最大值,然后返回那个值。
编码:
public static int computeMedian(int x, int y, int z)
{
if((x >= y && x <= z) || (x >= z && x <= y)) {return x;}
else if((y >= x && y <= z) || (y >= z && y <= x)) {return y;}
else if((z >= x && z <= y) || (z >= y && z <= x)) {return z;}
else { return 0; }
}
然后我在我的findPivot
方法中使用它,该方法采用当前array, from, to
值并使用它们来构造一个枢轴
这是该代码:
public static int findPivot(int[] a, int from, int to)
{
if(a.length <= 7)
{
return a[(to)/2];
}
else if(a.length > 7 && a.length <= 40)
{
return computeMedian(a[from], a[(to)/2] , a[to]);
}
else
{
int x = computeMedian(a[0 * (to) / 8], a[1 * (to) / 8], a[2 * (to) / 8]);
int y = computeMedian(a[3 * (to) / 8], a[4 * (to) / 8], a[5 * (to) / 8]);
int z = computeMedian(a[6 * (to) / 8], a[7 * (to) / 8], a[8 * (to) / 8]);
return computeMedian(x,y,z);
}
}
此方法适用于对任何小于或等于 40 的数组进行排序,但一旦它大于 40,我就会收到堆栈溢出错误,导致返回computeMedian
该else {}
部分中的方法。如果我把它放在那里,我会注意到它return computeMedian(a[from], a[(to)/2] , a[to]);
在 > 40 部分有效,但这只是 3 个值的中值,而不是 3 组中值的中值。
目前,这就是我findPivot
插入快速排序分区方法的方式:
private static int modPartition(int[] a, int from, int to)
{
int pivot = findPivot(a, from, to);
int i = from - 1;
int j = to + 1;
while(i < j)
{
i++; while (a[i] < pivot) { i++; }
j--; while (a[j] > pivot) { j--; }
if (i < j) { swap(a, i, j); }
}
return j;
}
computeMedian
我对为什么我的方法无法在更大的数据集上工作感到非常困惑。我尝试i * (n-1) / 8
通过 for 循环将值放入数组中,对它们进行排序并在中间返回值,以及将值放入数组中p
并调用computeMedian(computeMedian(p[0], p[1], p[2]), computeMedian(p[3],p[4],p[5]),...etc
,我得到了相同的堆栈溢出问题,但它往往会移动到我的代码的不同部分并引导我转圈。
如果有人需要,我可以发布更多片段,但我认为我的问题可能就在这里。
谢谢您的帮助。我仍在学习,我认为掌握这一点完全可以帮助我自己解决未来的问题。
以下是堆栈跟踪中的问题行: 第 16 行:int p = modPartition(a, from, to);
第 18modSort(a, p+1, to);
行 第 23 行int pivot = findPivot(a, from, to);
这也是我的整个 modSort 方法:
public static void modSort(int[]a, int from, int to)
{
if(from >= to) { return; }
int p = modPartition(a, from, to);
modSort(a, from, p);
modSort(a, p+1, to);
}