سؤال

Actually i have to create huffman tree for that i need to sort the frequency and i am using qsort() function for that. But when i try to display the frequency it show still the same pattern (Not the sorted one). Here is my code:-

        struct node
        {
            int value;
            char letter;                 /* symbol */
            struct node *left,*right;    /* left and right subtrees */
        };
    typedef struct node Node;
//Given below is the frequency of all 27 alphabets
int englishLetterFrequencies [27] = {81, 15, 28, 43, 128, 23, 20, 61, 71, 2, 1, 40, 24, 69, 76, 20, 1, 61, 64, 91, 28, 10, 24, 1, 20, 1, 130};

here is my function where i try to build huffman (its inside the main() ):

/*builds the huffman tree and returns its address by reference*/

    void buildHuffmanTree(Node **tree){
        Node *temp;
        Node *array[27];
        int i, subTrees = 27;
        int smallOne;

        for (i=0;i<27;i++)
        {
            array[i] = malloc(sizeof(Node));
            array[i]->value = englishLetterFrequencies[i];
            array[i]->letter = i;
            array[i]->left = NULL;
            array[i]->right = NULL;
        }
         smallOne=sorting(array); //this function is responsible for sorting. I HAVE QSORT() CALL IN THIS FUNCTION

    return;
}

see its function definition :

int sorting(Node *array[])
{
    int smaller;
    int i = 0; int d,p;
    printf("the array frequency is \n");
    for(d=0;d < 27;d++)
    printf("%d  ",*array[d]);
    // sorting of arrays
    qsort(array,27,sizeof(*array),&cmpfunc); 
    //////////////////////////
    printf("\n the sorted array frequency is \n");
        for(p=0;p < 27;p++)
    printf("%d  ",*array[p]);

    return smaller;
}

whereas the cmpfunc() is here like this //PROBABLY MISTAKE IS HERE

 int cmpfunc (const void * a, const void * b)
    {
          return ( ((Node *)a)->value - ((Node *)b)->value );
    }

Any idea why it don't sort the arrays ?

هل كانت مفيدة؟

المحلول 2

Your comparator is wrong, and your assumption of how qsort works isn't far behind it.

For sorting a pointer array of Node* you need a comparator like this:

int cmpfunc (const void * a, const void * b)
{
    const Node **lhs = (const Node **)a;
    const Node **rhs = (const Node **)b;
    return (*lhs)->value < (*rhs)->value ? -1
        : ((*rhs)->value < (*lhs)->value);
}

Stripping all the extraneous junk out, including the sorting() call and invoking qsort directly...

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

struct node
{
    int value;
    char letter;                 /* symbol */
    struct node *left,*right;    /* left and right subtrees */
};
typedef struct node Node;

static const int englishLetterFrequencies [27] =
{
    81, 15, 28, 43, 128, 23,
    20, 61, 71, 2, 1, 40, 24,
    69, 76, 20, 1, 61, 64, 91,
    28, 10, 24, 1, 20, 1, 130
};

int cmpfunc (const void * a, const void * b)
{
    const Node **lhs = (const Node **)a;
    const Node **rhs = (const Node **)b;
    return (*lhs)->value < (*rhs)->value ? -1
        : ((*rhs)->value < (*lhs)->value);
}

void buildHuffmanTree(Node **tree)
{
    Node *array[27];
    int i;
    
    for (i=0;i<27;i++)
    {
        array[i] = malloc(sizeof(*array[i]));
        array[i]->value = englishLetterFrequencies[i];
        array[i]->letter = (char)i;
        array[i]->left = NULL;
        array[i]->right = NULL;
    }
    
    qsort(array, 27, sizeof(*array), cmpfunc);
    
    for (i=0; i<27; ++i)
        printf("array[%d]->value = %d\n", i, array[i]->value);
    
    return;
}

int main()
{
    buildHuffmanTree(NULL);
    return 0;
}

Output

array[0]->value = 1
array[1]->value = 1
array[2]->value = 1
array[3]->value = 1
array[4]->value = 2
array[5]->value = 10
array[6]->value = 15
array[7]->value = 20
array[8]->value = 20
array[9]->value = 20
array[10]->value = 23
array[11]->value = 24
array[12]->value = 24
array[13]->value = 28
array[14]->value = 28
array[15]->value = 40
array[16]->value = 43
array[17]->value = 61
array[18]->value = 61
array[19]->value = 64
array[20]->value = 69
array[21]->value = 71
array[22]->value = 76
array[23]->value = 81
array[24]->value = 91
array[25]->value = 128
array[26]->value = 130

Spend some time learning how the algorithm works, and don't take shortcuts. You're going to need two comparator functions for what it looks like you're ultimately going to do (assuming I understand how you're planning on building your huffman tree).

نصائح أخرى

 return ( (*(int**)a) - (*(int**)b ));

This is casting a and b as "pointer-to-pointer-to-int", so by dereferencing them only once you then calculate the difference between two pointers. What you mean is:

 return ( (*(Node **)a)->value - (*(Node **)b)->value );

because whilst **(int**)a might work in this case it is massively confusing to anyone trying to understand the code.

Edit: sorry, I ended up missing a dereference there myself - fixed.

Also:

printf("%d  ",*array[d]);

should be

printf("%d  ",array[d]->value);

for the same reason.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top