英文:
Home-rolled Quicksort algorithm throwing stack overflow exception: finding next location of pivot in partition method
问题
这是我的快速排序代码,对于正常情况它是有效的,但对于数组中包含相同元素的情况,我的代码出现问题。在这种情况下,我考虑将等于枢轴的元素放在枢轴的左侧。请帮我找出代码中的逻辑错误:
public class Solution {
public static int partition(int input[], int si, int ei) {
int pivot = input[si], pivotPos = si, count = 0;
// 计算小于等于枢轴的元素数量,以便在枢轴左侧留出空间
for (int i = pivotPos + 1; i < input.length; i++) {
if (input[i] <= pivot)
count++;
}
// 交换枢轴和元素
input[si] = input[si + count];
input[si + count] = pivot;
pivotPos = si + count;
// 确保枢轴左侧的元素都小于等于枢轴,右侧的元素都大于枢轴
int i = si, j = ei, temp;
while (i < pivotPos && j > pivotPos) {
if (input[i] <= pivot)
i++;
else {
if (input[j] > pivot)
j--;
else {
temp = input[i];
input[i] = input[j];
input[j] = temp;
i++;
j--;
}
}
}
return pivotPos;
}
public static void quickSort(int input[], int si, int ei) {
if (si >= ei)
return;
int pivotPos = partition(input, si, ei);
quickSort(input, si, pivotPos - 1);
quickSort(input, pivotPos + 1, ei);
}
public static void quickSort(int[] input) {
quickSort(input, 0, input.length - 1);
}
}
输入测试案例:
4 3 8 4 6 5
期望输出:
3 4 4 5 6 8
我的代码在调用分区函数的地方引发堆栈溢出错误。
英文:
hey this is my quicksort code and its working for normal cases but not for those where the array have same elements and in that case i considered putting elements which are equal to pivot to the left side of pivot.Could anyone please rectify the logical mistake in my code:
public class Solution {
public static int partition(int input[],int si, int ei) {
int pivot = input[si],pivotPos = si,count = 0;
// counting no of elements less than pivot so that space can be left empty to left of pivot
for(int i = pivotPos+1; i<input.length;i++) {
if(input[i]<=pivot)
count++;
}
//swapping pivot with the element
input[si] = input[si+count];
input[si+count] = pivot;
pivotPos = si+count;
// ensuring all elements to the left of pivot are less and to the right are more
int i = si, j = ei,temp;
while(i<pivotPos && j>pivotPos) {
if(input[i]<=pivot)
i++;
else {
if(input[j]>pivot)
j--;
else {
temp = input[i];
input[i] = input[j];
input[j] = temp;
i++;
j--;
}
}
}
return pivotPos;
}
public static void quickSort(int input[], int si, int ei) {
if(si>=ei)
return;
int pivotPos = partition(input,si,ei);
quickSort(input,si,pivotPos-1);
quickSort(input,pivotPos+1,ei);
}
public static void quickSort(int[] input) {
/* Your class should be named Solution
* Don't write main().
* Don't read input, it is passed as function argument.
* No need to print or return the output.
* Taking input and printing output is handled automatically.
*/
quickSort(input,0,input.length - 1);
}
}
input test case:
4 3 8 4 6 5
expected output:
3 4 4 5 6 8
my code gives stack overflow error from the point where partition function is being called
答案1
得分: 0
我认为我已经修复了你的代码,同时最小程度地更改了你的代码风格。你会注意到,尽管我们实际上不需要它,但我保留了一些你的代码。我将它们留在那里供你对比。
public class QuickSort {
public static int partition(int input[], int si, int ei) {
int pivot = input[si], pivotPos = si, count = 0;
// 计算小于 pivot 的元素数量,以便在 pivot 左侧留出空间
for (int i = pivotPos + 1; i < input.length; i++) {
if (input[i] <= pivot) {
count++;
}
}
// 上面的 count 不是我们需要的信息
// 我们需要知道在 si 和 ei(包括)之间有多少个元素小于 pivot 的值
// 修正的逻辑在这里:
int smallerThanPivotCount = 0;
for (int i = si; i <= ei; i++) { // 请注意,我们的逻辑包括 ei
if (input[i] < pivot)
smallerThanPivotCount++;
}
// 交换 pivot 与元素
input[si] = input[si + smallerThanPivotCount];
input[si + smallerThanPivotCount] = pivot;
pivotPos = si + smallerThanPivotCount;
// 接下来
// 确保 pivot 左侧的所有元素都小于 pivot,右侧的所有元素都大于 pivot
int i = si, j = ei, temp;
while (i < pivotPos && j > pivotPos) {
if (input[i] <= pivot)
i++;
else {
if (input[j] >= pivot)
j--;
else {
temp = input[i];
input[i] = input[j];
input[j] = temp;
i++;
j--;
}
}
}
return pivotPos;
}
public static void quickSort(int input[], int si, int ei) {
if (si >= ei)
return;
int pivotPos = partition(input, si, ei);
quickSort(input, si, pivotPos - 1);
quickSort(input, pivotPos + 1, ei);
}
public static void quickSort(int[] input) {
/* 你的类应该命名为 Solution
* 不要写 main()。
* 不要读取输入,它作为函数参数传递。
* 无需打印或返回输出。
* 输入和输出处理都是自动完成的。
*/
quickSort(input, 0, input.length - 1);
}
}
我认为你的问题只是没有正确地计算向前移动 pivot 所需的空格数量。我已经编写了代码。我不能百分之百保证它是正确的,但它通过了我的一小部分单元测试,包括你自己的示例数组。我建议你自己检查它以理解逻辑。然后清理掉多余的部分,使它成为你自己的代码。祝好运。
英文:
I think I have fixed your code while making minimal changes to your code style. You'll notice that I left some of your code in even though it isn't what we actually need to do. I left that in for your comparison.
public class QuickSort {
public static int partition(int input[],int si, int ei) {
int pivot = input[si],pivotPos = si,count = 0;
// counting no of elements less than pivot so that space can be left empty to left of pivot
for(int i = pivotPos+1; i<input.length;i++) {
if(input[i]<=pivot) {
count++;
}
}
// the above var count is not the info we need
// we need to know how many elements between si and ei (inclusive)
// are less than the value of pivot
// corrected logic here:
int smallerThanPivotCount = 0;
for (int i = si; i <= ei; i++) { // note that our logic includes ei
if (input[i] < pivot)
smallerThanPivotCount++;
}
//swapping pivot with the element
input[si] = input[si + smallerThanPivotCount];
input[si + smallerThanPivotCount] = pivot;
pivotPos = si + smallerThanPivotCount;
// next we are
// ensuring all elements to the left of pivot are less and to the right are more
int i = si, j = ei,temp;
while(i<pivotPos && j>pivotPos) {
if(input[i]<=pivot)
i++;
else {
if(input[j]>=pivot)
j--;
else {
temp = input[i];
input[i] = input[j];
input[j] = temp;
i++;
j--;
}
}
}
return pivotPos;
}
public static void quickSort(int input[], int si, int ei) {
if(si>=ei)
return;
int pivotPos = partition(input,si,ei);
quickSort(input,si,pivotPos - 1);
quickSort(input,pivotPos+1,ei);
}
public static void quickSort(int[] input) {
/* Your class should be named Solution
* Don't write main().
* Don't read input, it is passed as function argument.
* No need to print or return the output.
* Taking input and printing output is handled automatically.
*/
quickSort(input,0,input.length - 1);
}
}
I think your problem was just that you didn't correctly count the number of spaces forward you needed to shift the pivot. I have written code. I don't guarantee you 100% that it is correct, but it does pass my short list of unit tests, including your own example array. I suggest examining it yourself to understand the logic. Then clean up the extra stuff and make it your own. Cheers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论