我想问一个快速排序分区函数的问题()。如果我替换声明
int pivot = arr[(left + right) / 2];
带
int pivot = arr[left+(right-left)>>1];
当数组中存在重复元素时,算法不起作用。为什么?感谢。
int partition(int arr[], int left, int right)
{
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2]; **********
while (i <= j) {
while (arr[i] < pivot) i++;
while (arr[j] > pivot) j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
}
return i;
}
答案 0 :(得分:2)
问题是运营商的优先顺序。
您使用的3的顺序如下:
会发生什么,left+(right-left)>>1
被视为(left+(right-left))>>1
,它不相等,而只是right >> 1
或right / 2
。
您可以在此处查看优先顺序:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
答案 1 :(得分:0)
使用
int pivot = arr[left+(right-left)>>1];
你实际上在写
int pivot = arr[(left+(right-left))/2];
等于
int pivot = arr[right/2];
因此,您选择的是与第一个代码不同的枢轴元素。但是,只要您选择的pivot元素在当前子数组的范围内,快速排序就应该返回正确的解决方案。通过修改,您最终将选择一个不在当前子阵列中的枢轴元素。