C中的快速排序实现

时间:2013-11-23 22:18:30

标签: c quicksort qsort

回答每个人的第一个问题:是的,这是针对学校的。 话虽这么说,我觉得我已经非常接近让这个工作,至少部分。似乎对大多数数据进行排序,但我看不到任何未排序的模式。

#include <stdio.h>
#include <stdlib.h>

void quicksort(int *values, int size);
void printout(int[], int size);

void main(){
    printf("starting");
    int size=20;
    int values[size];
    int i;
    for (i=0;i<size;i++){
        values[i]=(rand()%113);
    }
    printf("\nBefore Sort:\n");
    printout(values,size);
    quicksort(values, size);
    printf("\nAfter Sort:\n");
    printout(values,size);
}

void printout(int values[],int size){
    int i;
    for (i=0;i<size;i++){
        if (i % 20 == 0){
            printf("\n");
        }
        printf("%3i ", values[i]);
    }
}

void quicksort(int *values, int size){
    if (size < 2){
        return;
    }
    int pivot=values[size];
    int left[size];
    int right[size];
    int center[size];
    int i,lc,rc,cc;  //counters for left, right and center arrays
    lc=rc=cc=0; //initially 0

    for (i=0; i<size-1; i++){
        if (values[i] < pivot){
            left[lc]=values[i];
            lc++;
        }
        else if (values[i] > pivot){
            right[rc]=values[i];
            rc++;
        }
        else{
            center[cc]=values[i];
            cc++;
        }
    }
    quicksort(left, lc);
    quicksort(right, rc);
    int lc2,rc2,cc2;
    lc2=rc2=cc2=0;  //note the first variable is lowercase L, not 1
    while (lc2+cc2+rc2 < size-1){  // here we recombine our arrays
        while (lc2 < lc){
            values[lc2+rc2+cc2] = left[lc2];
            lc2+=1;
        }
        while (cc2 < cc){
            values[lc2+rc2+cc2] = center[cc2];
            cc2+=1;
        }
        while (rc2 < rc){
            values[lc2+rc2+cc2] = right[rc2];
            rc2+=1;
        }
    }

}

我的输出如下:

排序前:

41 48 6 58 72 17 65 91 68 56 55 8 3 103 17 39 57 77 81 12

排序后:

6 8 17 41 48 58 72 65 68 56 55 3 17 39 91 57 77 103 81 12

它肯定在做某事......任何人都对我在这里缺少什么有任何想法?

2 个答案:

答案 0 :(得分:0)

您选择的枢轴错误 - values[size]位于范围之外。如果要使用最后一个元素,请使用values[size - 1]

答案 1 :(得分:0)

我已经提供了有关调试的提示,您可以在将来应用这些提示来查找这些问题。

问题1

int pivot=values[size];

大小超出了排序范围的末尾。在顶层,当范围是整个数组时,意味着它在数组之外。而在其他级别,它要么在数组之外,要么在数值不同的范围内。

发现此缺陷可能需要仔细检查代码或设计用于捕获此类错误的工具,例如内置于某些编译器中的错误。

更困难的方法是使用print语句或调试器检查运行时行为,并识别第一个pivot不是数组中的值。使用已知输入而不是随机输入进行测试有助于使用此方法,因为它使您更有可能发现任何意外情况。


问题2

您也不会将枢轴移动到正确的位置。

发现这种情况的一种方法是检查后置条件。例如,在quicksort()的末尾,应该对范围进行排序。因此,如果您在该函数的末尾插入printout(values,size);,那么在一些短的情况下可能会注意到最后一个元素出现故障。其他打印语句可以帮助您追踪导致此问题的原因。


问题3

main()必须返回int,而不是void

使用更严格的编译器将为您捕捉到这一点。