C String Quicksort

时间:2013-01-30 05:44:55

标签: c quicksort

目前正试图弄清楚这种问题是什么。直接从维基百科的就地Quicksort伪代码构建,我将假设它是可靠的。我试图通过以null结尾的3个字符的“代码”字段对结构数组进行排序。

排序主要起作用,但总有一些元素不合适。我只能假设这与枢轴有某种关系,但我已经花了几个小时盯着它而已经无处可去。谢谢!

void quicksort(Cdir *directory, int left, int right) {

    if (left < right) {
        int pivotIdx = left;
        pivotIdx = partition(directory, left, right, pivotIdx);
        quicksort(directory, left, pivotIdx - 1);
        quicksort(directory, pivotIdx + 1, right);
    }
}

int partition(Cdir *directory, int left, int right, int pivot) {

    char *pivotVal = directory[pivot].code;
    int curIdx = left;
    swap(&directory[pivot], &directory[right]);

    int i;
    for (i = left; i < right; i++) {
        if (strncmp(directory[i].code, pivotVal, 3) < 0) {
            swap(&directory[i], &directory[curIdx]);
            curIdx++;
        }
    }
    swap(&directory[curIdx], &directory[right]);
    return curIdx;
} 

void swap(Cdir *s1, Cdir *s2) {

    Cdir temp = *s1; 
    *s1 = *s2;
    *s2 = temp;
}

4 个答案:

答案 0 :(得分:3)

我只想说出来......请不要将此视为您问题的实际答案,因为事实并非如此。

作为程序员,您将花费几乎所有时间自己解决问题。这是一个开始学习如何做到这一点的机会。如果你养成了通过实验找出你的程序以某种方式表现的原因的习惯,那么你将成为比那些只是问人们错误的人更好的程序员。

盯着代码可以让你达到目的,但是如果没有看到实际使用的数据,你就不会总是超过这一点。这就是调试的全部内容:了解程序的位置,正在执行的操作以及变量包含的内容。

调试代码的最简单方法是使用printf告诉您发生了什么。

想象一下,如果您的程序输出如下:

Quicksorting on range 1 to 6
Partitioning on range 1 to 6
  Sub-array before:
    bob
    nelly
    harold
    yasmine
    fred
    roger
  Sub-array after:
    (you get the idea)
Partition returned pivot index of 5
Quicksorting on range 1 to 4
  (etc etc)

嗯,它可以。插入几个printf调用非常容易,突然间你从程序中获得了一个大量的输出,你可以将其写入文件然后查看。如果发生了一些愚蠢的事情,很快就会变得很明显,只需花一点时间就可以为你的代码添加一些痕迹并重新编译。

快乐的编码。

答案 1 :(得分:2)

分区(..)中的这一行有一个错误:

for (i = left; i < right - 1; i++)

维基百科中的代码假定右边1包含在循环中,应该是&lt; =。

答案 2 :(得分:2)

我终于明白了。当我在字符串比较中替换“pivotVal”并直接引用数据透视值(目录[右])时,排序工作正常。仍然试图决定为什么,但它是固定的!

void quicksort(Cdir directory[], int left, int right) {

    if (left < right) {
        int pivotIdx = left;
        pivotIdx = partition(directory, left, right, pivotIdx);
        quicksort(directory, left, pivotIdx - 1);
        quicksort(directory, pivotIdx + 1, right);
    }
}

int partition(Cdir directory[], int left, int right, int pivot) {

    int curIdx = left;
    swap(&directory[pivot], &directory[right]);

    int i;
    for (i = left; i < right; i++) {
        if (strncmp(directory[i].code, directory[right].code, 3) < 0) {
            swap(&directory[i], &directory[curIdx]);
            curIdx++;
        }
    }
    swap(&directory[curIdx], &directory[right]);

    return curIdx;
} 

void swap(Cdir *s1, Cdir *s2) {

    Cdir temp = *s1; 
    *s1 = *s2;
    *s2 = temp;
}

答案 3 :(得分:0)

我不认为你应该将for循环更改为i&lt; =正确,因为glagolig建议因为swap(pivot,right)和i&lt;右边是从数组中删除数据,并处理较小的数组1元素。 算法对我来说看起来非常正确,可能问题在于你如何调用函数 你应该使用right参数调用函数作为数组中的最后一个索引而不是数组的大小,即如果你有Cdir arr [10];你应该打电话给quicksort(arr,0,9);
如果您发布错误输出的输入示例,您也可以帮助人们提供更多帮助 我会添加这个作为评论,但我没有足够的代表这样做: - )