C 字符串快速排序

C 字符串快速排序,c,quicksort,C,Quicksort,目前正试图找出这类问题的症结所在。直接从Wikipedia的即时快速排序伪代码构建,我将假设它是可靠的。我正在尝试按以空结尾的3字符“代码”字段对结构数组进行排序 这种方法基本上是有效的,但总有一些元素不合适。我只能想当然地认为这与枢轴有关,但我花了几个小时盯着它看,结果一无所获。谢谢 void quicksort(Cdir *directory, int left, int right) { if (left < right) { int pivotIdx =

目前正试图找出这类问题的症结所在。直接从Wikipedia的即时快速排序伪代码构建,我将假设它是可靠的。我正在尝试按以空结尾的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;
}
void快速排序(Cdir*目录,左整数,右整数){
if(左<右){
int pivotIdx=左;
pivotIdx=分区(目录,左,右,pivotIdx);
快速排序(目录,左侧,数据透视IDX-1);
快速排序(目录,pivotIdx+1,右);
}
}
int分区(Cdir*目录、int左、int右、int轴){
char*pivotVal=目录[pivot]。代码;
int curIdx=左;
交换(&directory[pivot],&directory[right]);
int i;
for(i=left;i
您在分区(..)的这一行中有一个bug:

for(i=left;i

wikipedia中的代码假设right-1包含在循环中,应该是我认为您不应该将for循环更改为I我只想说。。。请不要认为这是你的问题的实际答案,因为它不是。

作为一名程序员,你将花费几乎所有的时间独自解决问题。这是一个开始学习如何做到这一点的机会。如果你养成了通过实验找出你的程序为何以某种方式运行的习惯,你将成为一个比只问别人出了什么问题的人要好得多的程序员

盯着代码看可以让你到达一个点,但是你不可能总是在看不到实际使用的数据的情况下通过那个点。这就是调试的全部内容:知道程序在哪里,它在做什么,以及它的变量包含什么

调试代码最简单的方法是使用
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
调用非常容易,然后突然从程序中获得大量输出,然后将其写入文件并查看。如果发生了一些愚蠢的事情,它将很快变得明显,只需花一点时间就可以向代码中添加一些跟踪并重新编译


快乐的编码。

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

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;
}
void快速排序(Cdir目录[],左整数,右整数){
if(左<右){
int pivotIdx=左;
pivotIdx=分区(目录,左,右,pivotIdx);
快速排序(目录,左侧,数据透视IDX-1);
快速排序(目录,pivotIdx+1,右);
}
}
int分区(Cdir目录[],int-left,int-right,int-pivot){
int curIdx=左;
交换(&directory[pivot],&directory[right]);
int i;
for(i=left;i
你为什么要手工编写快速排序而不是仅仅使用标准库
qsort
?这是学校作业的一部分,其中一个要求是你自己编写排序。我可以很容易地写一个插入排序或冒泡排序之类的东西,但是写一个你已经知道如何写的排序有什么乐趣呢?;)@Yuushi我想你自己写qsort是因为他在学习谢谢!有趣的是,这并不能完全解决这个问题(尽管它离问题更近了)。我非常清楚这一点,并且喜欢编程所呈现的解决问题的方面。但是有时候最好的调试方法就是让别人看你的代码两秒钟。我希望这是一个我刚刚忽略的简单错误,并且会立即被具有外部视角的人注意到,但不幸的是,事实并非如此。不过,我同意你的观点——很多人在学习编写代码的同时使用SO作为一种避免不得不解决自己问题的方法,这是非常缺乏纪律性的。这很好,我不是故意粗鲁或居高临下。这一原则仍然有效。您要做的第一件事是说“为什么我的程序会这样运行?”,输入一些调试信息几乎总是比向从未见过代码的人显示和/或解释代码要快。如果您不能回答“在调用Y和Z之后,第X行上的程序状态是什么”的问题,那么您还没有准备好请其他人查看您的代码。你养成的这个习惯越多,你问的“bug在哪里”的问题就越少。很高兴你最终发现了你的问题。你当然是对的。如果这让你感觉更好,你的反应就是促使我再次尝试调试并最终发现错误的原因。所以谢谢你!:)哈哈,所以这毕竟是一个答案;-)有趣。你的Cdir是什么?快速提问。。。为什么只比较字符串的三个字符?您不应该比较整个字符串吗?所讨论的字符串是一个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) {

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