我一直在尝试将quickselect算法作为家庭作业的一部分来实施。我已经阅读了quicksort的工作方式,了解分区是如何工作的,并找到五个元素的中位数等。但是当谈到分区时,我就是在喝汤。
我意识到我的分区结果不包含(less than pivot) | pivot | (greater than pivot)
形式的元素。我一直在打破这个问题,但我似乎无法理解它。
我从维基百科改编的快速选择算法,我正在使用迭代版本(我提到的要求)。我的quickselect算法如下:
public static Numbers quickselect(Numbers[] list, int arraylength,
int kvalue) {
int start = 0, end = arraylength - 1;
if (arraylength == 1)
return list[start];
while (true) {
int newPivotIndex = partition(list, start, end);
int pivotDist = newPivotIndex - start + 1;
if (pivotDist == kvalue)
return list[newPivotIndex];
else if (kvalue < pivotDist)
end = newPivotIndex - 1;
else {
kvalue = kvalue - pivotDist;
start = newPivotIndex - 1;
}
}
我的分区算法:
private static int partition(Numbers[] list, int start, int end) {
Numbers[] tempMedianArray = new Numbers[5];
tempMedianArray[0] = list[start];
tempMedianArray[1] = list[(start + end) / 4];
tempMedianArray[2] = list[(start + end) / 12];
tempMedianArray[3] = list[(start + end) / 2];
tempMedianArray[4] = list[end];
Numbers pivot = getmedian(tempMedianArray);
int i = start, j = end;
while (i <= j) {
while (compare(list[i], pivot).equals(Order.LESSER)){
i++;
}
while (compare(list[j], pivot).equals(Order.GREATER)){
j--;
}
if (i <= j) {
Numbers tmp = list[i];
list[i] = list[j];
list[j] = tmp;
}
};
一旦选择了枢轴,我认为标准的Hoare算法是可行的。但是当我进行干跑时,我知道我错了。
有人可以帮助我正确实现分区算法,该算法的中位数为5个支点吗?
答案 0 :(得分:0)
怎么样:
tempMedianArray[0] = list[start];
tempMedianArray[1] = list[(start + end) / 4];
tempMedianArray[3] = list[(start + end) / 2];
tempMedianArray[2] = list[3 * (start + end) / 4];
tempMedianArray[4] = list[end];
答案 1 :(得分:0)
您必须在获取临时数组索引时继续添加开始。
int localStart = 0;
int localEnd = end - start;
Number[] local = new Number[5];
tempMedianArray[0] = list[localStart + start];
tempMedianArray[1] = list[(localStart + localEnd) / 4 + start];
tempMedianArray[2] = list[(localStart + localEnd) / 4 * 3 + start];
tempMedianArray[3] = list[(localStart + localEnd) / 2 + start];
tempMedianArray[4] = list[localEnd + start];