C(初学者):为什么我的qsort不起作用?编辑:从一个错误到另一个错误

时间:2010-10-19 16:59:22

标签: c algorithm struct qsort

我正在进行K& R练习6-4,这是:

  

6-4。编写一个程序,在其输入中打印不同的单词,按照出现频率的降序排列。按其数量排在每个单词之前。

我决定做的是创建一个名为dstncFreqNode6_4的结构:

struct dstncFreqNode6_4
{
   char *word;
   int count;
   struct dstncFreqNode6_4 *left;
   struct dstncFreqNode6_4 *right;
};

然后我解析了单词的输入,并为每个不同的单词创建了一个“dstncFreqNode6_4”节点和两个指针:一个插入BST(添加新单词/更新已经遇到的单词的计数),和一个插入“dsntFredNode6_4”指针的全局数组。

这样做是为了通过遍历BST(其中包含到目前为止遇到的所有单词的指针)来更新单词(节点)的计数。解析完整个输入后,指针数组将按成员的“计数”变量排序,然后打印。

添加新单词/更新计数的代码在这里:(我认为它没有任何问题,因为BST和数组似乎是正确填充的,所以你可以忽略它)< / EM>:

//"wordCounts" is originally a global dstncFreqNode6_4** declared outside the function, numWords is the current length of the array

struct dstncFreqNode6_4 *addFreqNode6_4(struct dstncFreqNode6_4 *root, char *word)
{

    if(root == NULL)
    {

       root = (struct dstncFreqNode6_4 *) malloc(sizeof(struct dstncFreqNode6_4));
       root -> word = word;
       root -> count = 1;

       root -> left = NULL;
       root -> right = NULL;


       struct dstncFreqNode6_4 **p;

       wordCounts = (struct dstncFreqNode6_4 **) realloc(wordCounts, sizeof(struct dstncFreqNode6_4*) * (numWords +1));
       p = wordCounts + numWords++;

       (*p) = root;

    }
    else if(strcmp(word, root -> word) < 0)
        root -> left = addFreqNode6_4(root -> left, word);
    else if(strcmp(word, root -> word) > 0)
        root -> right = addFreqNode6_4(root -> right, word);
    else
        root -> count++;

return root;

}

所以除了排序之外我还能正常工作;它根本不会对数组进行排序。也就是说... 元素的顺序保持不变 编辑:我收到分段错误。 编辑#2: 现在没有分段错误;原来的问题仍然存在。

我正在使用stlib.h的qsort方法;我正在使用的比较功能是:

int qcmp6_4(const void *a, const void *b)
{
    return (*(struct dstncFreqNode6_4 **)a) -> count - (*(struct dstncFreqNode6_4 **)b) -> count;
}

我似乎无法弄清楚为什么它不能正确排序。我实际上实现了自己的快速排序算法,并得到了相同的结果。我现在真的不知道。

让一些新鲜的,专业的眼睛指向正确的方向会很好。感谢。

修改

对不起,这是对qsort的调用:

qsort(wordCounts, numWords, sizeof(struct dstncFreqNode6_4 *), qcmp6_4);

编辑#2:

根据这个建议,我已经将“wordCounts”作为一个指向节点的指针数组(此帖子中的所有代码都已更新以反映此)。所以本质上,BST和数组包含相同的信息(实际上数组指针被初始化为BST中的相应指针),但它们的用途是不同的。 BST用于添加新单词/更新已经遇到的单词的数量,并且数组在末尾(通过每个单词'计数)排序并打印。但是,我遇到了我最初遇到的同样问题:在调用qsort之后,数组的顺序保持不变。

2 个答案:

答案 0 :(得分:0)

在我看来,您正在尝试对节点数组进行排序,每个节点都包含指向数组中其他节点的指针。排序后,这些指针当然会指向数组的错误元素。也许那是你的问题?

顺便说一下,我看到你正在使用realloc。每当必须将分配的数组移动到新位置以满足新的大小要求时,指向数组元素的指针就会出现realloc,只会更糟糕:节点指针现在都将指向无效地址并使用它们将导致未定义的行为。

一种可能的解决方案是永远不要修改原始的节点数组,而是创建第二个指向节点的数组,并使用比较函数对指针数组进行排序,比较它们指向的节点到。

答案 1 :(得分:0)

所以我设法用自己的quicksort实现来排序。 stlib.h的版本仍然没有排序我的数组。它只能用于原始类型的数组吗?因为这是我能看到的阻止它工作的唯一原因。

这是我的自定义qsort代码供参考:

void swapFreq6_4(struct dstncFreqNode6_4 **a, struct dstncFreqNode6_4 **b)
{
   struct dstncFreqNode6_4 *t=*a; *a=*b; *b=t;
}

void **sortFreq6_4(struct dstncFreqNode6_4 **arr, int beg, int end)
{

   if (end > beg + 1)
   {
      struct dstncFreqNode6_4 *piv = *(arr + beg);
      int l = beg + 1;
      int r = end;


     while (l < r)
     {
         if ( (*(arr + l))-> count <= piv -> count)
             l++;
         else
             swapFreq6_4((arr + l), (arr + --r));
     }



     swapFreq6_4((arr + --l), (arr + beg));
     sortFreq6_4(arr, beg, l);
     sortFreq6_4(arr, r, end);

  }
}

有谁知道为什么stdlib的qsort代码不适用于我的struct?我使用它错了(我对它的调用,以及比较功能都在原帖中)?