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

时间:2015-09-30 15:47:06

标签: c++ quicksort

所以我遇到了一个快速排序整数数组的c ++程序的问题。当我的数组中有六个以上的元素时,由于某种原因,该类无限循环。我认为我已经将问题与选择mm关键值相提并论,但我无法解决为什么它会导致它破裂。

#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它是子列表中的最后一项。

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

如果运行,就像现在的程序一样,将在无限循环后进行段错误,但如果正在排序的数组是一个较短的元素,它将正常工作。这让我困惑了几个小时,我无法解决问题所在。如果有人有任何提示或建议,他们将不胜感激。

2 个答案:

答案 0 :(得分:0)

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之间的索引。

答案 1 :(得分:0)

您还可以使用三种方法的中位数作为您的支点。它更健壮一点。

#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;
 }