c++递归快速排序无限循环

c++ recursive quicksort infinite loop

本文关键字:无限循环 快速排序 递归 c++      更新时间:2023-10-16

所以我一直有一个问题与c++程序快速排序的整数数组。当我的数组中有超过六个元素时,由于某种原因,排序就会无限循环。我想我已经把问题隔离到关键值的选择上了,但是我无论如何也弄不明白为什么它会导致它坏掉。

#include<iostream>
using namespace std;
int getPivot(int begin,int end){//Takes length of array as input and returns the position of the pivot
    int len = end-begin;
    if(len < 3){
        return end;
    }else{
        return 2;
    }
};
void quickSort(int begin, int end, int arr[]){
    int pivot = arr[getPivot(begin,end)];//get Pivotal value - If I replace this with just 0 then there are no problems...
    int tempLeft = begin, tempRight = end;
    int temp;
    while(tempLeft <= tempRight){
        while(arr[tempLeft] < pivot){//Find a point where there are 2 elements that need to be swapped
            tempLeft++;
        }
        while(arr[tempRight] > pivot){
            tempRight--;
        }
        if(tempLeft <= tempRight){
            temp = arr[tempLeft];//Swap the elements
            arr[tempLeft] = arr[tempRight];
            arr[tempRight] = temp;
            tempLeft++;//Skip these swapped elements in the sort
            tempRight--;
        }
    }
    if (begin < tempRight){//Only recurse lower if the new sub array has a length greater than 1
        quickSort(begin, tempRight, arr);
    }
    if (tempLeft < end){
        quickSort(tempLeft, end, arr);
    }
}
main() {
    int array[] = {0,1,2,3,4,5,6};
    int length = 7;
    quickSort(0,length-1,array);
}

你可能会问为什么我有这样一个奇怪的方式来选择我的枢纽值,但让我们说,在这个例子中,枢纽值必须是每个子列表中的第三个元素,或者如果子列表小于3,它是子列表中的最后一项。

我认为问题与枢纽值有关的原因是,当我用子列表中的第一个元素取代选择枢轴的方法时,我没有任何问题。

如果运行,就像现在的程序一样,将在无限循环后出现分段故障,但如果正在排序的数组短一个元素,它将正常工作。这已经让我困惑了好几个小时了,我不知道是什么问题。如果有人有任何提示或建议,我将不胜感激。

quickSort(3,6,arr)将始终调用quickSort(3,6,arr)

我想你错过了

int getPivot(int begin,int end)
{
    //Takes length of array as input and returns the position of the pivot
    int len = end-begin;
    if(len < 3){
        return end;
    }else{
        return 2+begin; // Here
    }
};

编辑:澄清

GetPivot(3,6)将返回2,而不是返回3到6之间的索引。

您也可以使用三种方法的中位数作为枢轴。它更健壮一些。

#include<iostream>
using namespace std;
void myswap(int* arr, int left, int right)
{
    int swap = arr[left];
    arr[left] = arr[right];
    arr[right] = swap;
}
int getPivotIndex(int* arr, int begin, int end){
    int middle = (begin + end) / 2;
    if (arr[end] < arr[begin])
    {
        myswap(arr, begin, end);
    }
    if (arr[middle] < arr[begin])
    {
        myswap(arr, middle, begin);
    }
    if (arr[end] < arr[middle])
    {
        myswap(arr, end, middle);
    }
    return middle;
};

void quickSort(int begin, int end, int* arr){
    int pivot = arr[getPivotIndex(arr, begin, end)];
    int tempLeft = begin, tempRight = end;
    while (tempLeft <= tempRight){
        while (arr[tempLeft] < pivot){
            tempLeft++;
        }
        while (arr[tempRight] > pivot){
            tempRight--;
        }
        if (tempLeft <= tempRight){
            myswap(arr, tempLeft, tempRight);
            tempLeft++;
            tempRight--;
        }
     }
    if (begin < tempRight){
        quickSort(begin, tempRight, arr);
    }
    if (tempLeft < end){
        quickSort(tempLeft, end, arr);
    }
}
int main() {
    int array[] = { 6, 0, 2, 5, 4, 3, 1 }; // Test we are actually sorting
    int length = 7;
    quickSort(0, length - 1, array);
    for (int i = 0; i < length; i++)
    {
        std::cout << "array[" << i << "]: " << array[i] << endl;
    }
    return 0;
 }