C中的QuickSort无限循环?

时间:2016-10-05 17:10:52

标签: c infinite-loop quicksort

我在快速排序算法中面临无限循环问题,这件事发生在右子数组分区中,所以如果我只对左子数组进行分区,它就像这段代码一样。

#include <stdio.h>
int list[] = {8, 1, 3, 4, 2, 10, 4, 6};
//int list[] = {2, 1, 10, 4, 5, 11, 12, 6};
//int list[] = {1, 2, 4,  5, 6, 11, 12, 10};
int main(int argc, char **argv)
{

    printf("Unsorted list is: ");
    printArray(list);
    quickSort(list, 0, 7);
    //partition(list, 5, 7);
    printf("Sorted list is: ");
    printArray(list);

    return 0;
}

void printArray(int list[]){
    int i;
    for(i = 0; i < 8; i++){
        printf(" %d ", list[i]);
    }   
    printf("\n\n");
}

void quickSort(int list[], int low, int high){

    int pIndex = partition(list, low, high);

    if(pIndex <= 0){
        return;
    }

    //quick sort left sub array
    quickSort(list, low, pIndex-1);

    //quick sort right sub array
//  quickSort(list, pIndex+1, high);

    printf("pIndex is %d\n", pIndex);
}

int partition(int list[], int low, int high){
    int pivot = list[high];


    int i;
    int j = high - 1;
//  int j = high;


    while( 1 ){
        //less than pivot
        for(i = 0; list[i] < pivot; i++){
            printf("for %d (index %dth) < %d\n", list[i], i, pivot);
            //do nothing
        }
        printf("less than stop at index %d which is %d\n", i, list[i]);

        //more than pivot
        for(j = j; j > 0 && pivot < list[j]; j--){
            printf("for %d < %d (index %dth)\n", pivot, list[j], j);
        }
        printf("greater than stop at index %d which is %d\n", j, list[j]);

        if(i >= j){
        printf("low index %d >= %d then swap pivot\n", i, j);
        printf("swap index %dth which is %d, with index pivot %d which is %d\n", i, list[i], high, list[high]);
        swap(list, i, high);

        printf("Temporary list is: ");
        printArray(list);

        printf("then return last position index pivot %d which is %d\n", i, list[i]);
        return i;
        break;
        }

        //tukarPosisi, sehingga yang kecil di sebelah kiri, yang besar di sebelah kanan.
        printf("swap index %dth which is %d, with index %dth, which is %d\n", i, list[i], j, list[j]);
        swap(list, i, j);

        printf("Temporary list is: ");
        printArray(list);


    }
}

void swap(int list[], int i, int j){
    //variabel sementara untuk menampung i
    int temporary = list[i];

    //tukar posisi, sehingga yg kecil di kiri, yg besar di kanan.
    list[i] = list[j];
    list[j] = temporary;
}

我已经打印了很多调试,但仍然无法弄清楚为什么会发生这种情况。 那么逻辑错误在哪里以及如何解决它?

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题,主要是影响其效率而不是正确性。其中一些人在评论中被提出。然而,最大的问题是递归的终止条件,正如您可能预期的那样,这是错误行为的性质。

具体来说,当partition()返回小于或等于零的值时,递归最低点,但该函数始终返回为枢轴选择的最终位置。如果你只是向下递减分区的左侧,那么你肯定最终会得到零,但当你递减任何不包含元素0的分区时,partition()将永远不会返回0

您应该根据要排序的段的大小(即high - low)来断开递归。如果它小于1则可以停止,因为具有少于两个元素的段肯定已经按排序顺序。