кодирование Хаффмана с использованием C - PullRequest
0 голосов
/ 19 октября 2018

, поэтому я нажал на блок с моим кодом, и я просто не могу понять, почему я в самом конце пытаюсь распечатать строку с закодированными двоичными цифрами для дерева Хаффмана.Я использовал gdb для двойной проверки своей работы, и я просто не могу понять, почему моя функция printbin () просто не работает, она должна кодировать обход дерева .. Кто-нибудь может мне помочь?

#include    "h_node.h"
#define     ASCII 256


/* How to check if we are at the leaflet */

int isLeaf(h_node *root) {

    return !(root->left) && !(root->right); 
} 


/* To print the codes  */
void printBin(h_node *root,char arr[], int n) {

    /* To assign 0 */
    if (root -> left){
        arr[n] = 0;
        printBin(root -> left, arr, ++n);
    }


    /* To assign 1 */
    if (root -> right){
        arr[n] = 1;
        printBin(root -> right, arr, ++n );
    }

   //  Check if we are at the leaf 
    if (isLeaf(root)){
        int i;
        printf(" \n %c: ", root -> letter);
        for (i = 0; i < n; i++)
            printf("%d", arr[i]);
        printf("\n");

    }

}

/*  Creating the treeNode */
h_node *createNode(char a, int i, h_node *l, h_node *r) {
    h_node *node = calloc(1,sizeof(h_node));
    if (node) {
        node -> letter = a;
        node -> freq = i;
        node -> next = NULL;
        node -> left = l;
        node -> right = r;       
    }
   return node;
}


/*   Function to check size of file */

off_t fsize(const char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
        return 0;
}   


/*  Sorting algorithm */
void h_sort(h_node a[], int size){
    for (int c = 0; c < (size-1); c++) {
        int pos = c;
        if ( a[c].freq != 0 ) {
            for (int d = c + 1; d < size; d++) {
                if(a[pos].freq > a[d].freq)
                    pos = d;   
            }
            if ( pos != c ) {
                h_node swap = a[c];
                a[c] = a[pos];
                a[pos] = swap;
            }   
        }
    }
}
///////////////////////////////////////////////////////////
int compare(h_node *one, h_node *two) {
   int result;
   result = (one -> freq) - (two -> freq);
   if(!result) {
      result = (one -> letter) - (two -> letter);
   }
   return result;
}
////////////
h_node *insert_ll(h_node *ll, h_node *t) {

   h_node *temp;

   if(!ll || (compare(ll, t) > 0)) {
      t -> next = ll;
      temp = t;
   } else {
      temp = ll;

      while(ll -> next && (compare(ll -> next, t) < 0)) {
         ll = ll -> next;
      }

      t -> next = ll -> next;
      ll -> next = t;
   }

   return temp;
}
////////////////////
h_node *insert_tree(h_node *list, h_node *new) {

   h_node *temp;

   if(!list || new -> freq <= list -> freq) {
      new -> next = list;
      temp = new;
   }else{
      temp = list;

      while(list -> next && list -> next -> freq < new -> freq) {
         list = list -> next;
      }

      new -> next = list -> next;
      list -> next = new;
   }

   return temp;
}


/* This will parse my sorted list and take two structures at a time  */
h_node *create_tree(h_node *list) {

   h_node *new, *head, *left, *right;
   int sum;

   head = list;

   while(head -> next != NULL) {

      left = head;
      head = head -> next;

      /*
       * If head is null, end of list has been reached
       */
      if(!head) {
         break;
      }


      right = head;
      head = head -> next;

      sum = (left -> freq) + (right -> freq);

      if (left -> freq > right -> freq)
        new = createNode(left -> letter, sum, left, right);
      if (left -> freq == right -> freq)
        new = createNode(left -> letter,sum,left,right);
      if (left -> freq < right -> freq)
        new = createNode(right -> letter,sum,left,right);

      head = insert_tree(head, new); 
   }

   return head;
}

void treeprint(struct h_node *p){
    if ( p != NULL ){
        treeprint(p->left);
        printf("\n %d %x \n",p->freq, p->letter);
        treeprint(p->right);
    }
}



/*  Sorting algorithm */
void sort(int a[], int size){
    for (int c = 0; c < (size-1); c++) {
        int pos = c;
        if ( a[c] != 0 ) {
            for (int d = c + 1; d < size; d++) {
                if(a[pos] > a[d])
                    pos = d;   
            }
            if ( pos != c ) {
                int swap = a[c];
                a[c] = a[pos];
                a[pos] = swap;
            }   
        }
    }
}

/*  Finding the frequency */
void freq(char a[],int d[]) {

    int c = 0;

    while (a[c] != '\0'){ 
        d[(int)a[c]]++;
        c++;
    }

}



/* Start of Main  */

int main ( int argc, char *argv[] ){




    char ch;
    FILE *fp;    
    int i=0;
    int j = 0;
    int sameness = 0;
    int size = fsize(argv[1]);
     h_node *head = NULL;
      //h_node *new;


    printf("The size is %d\n",size);

    fp = fopen(argv[1], "r"); // read mode

    if (fp == NULL)
    { 
       perror("Error while opening the file.\n");
       exit(EXIT_FAILURE);
    }

    /* Now we create that array of size .. size */
    char *arr =calloc(fsize(argv[1]),sizeof(char));  
    int *count =calloc(ASCII,sizeof(int));

    printf("The size of the file is %ld\n",fsize(argv[1])); 

    /* This will copy each charater from the file into an array  */
    while((ch = fgetc(fp)) != EOF){
          arr[i++] = ch;
          fflush(fp);
    }     

    /* This is just to check to make sure everything properly prints out */
    printf("The contents of the file are:\n"); 
    for (int i = 0; i <= size-1; i++)
        printf("%c ", arr[i]);

    /* Now we want to selection sort the array so that it is in ascii value  */
    printf("\nThis is i : %d\n", i); 

    /* Now we want to count frequency */
    freq(arr,count);

    /* Now we want to sort by Frequency */
    //sort(count,256); 
    printf("\n");
    for (i = 0; i < ASCII; i++){
        if(count[i] != 0){
            sameness +=1;
            printf("%c %d\n ",i,count[i]);  
        }
    }

    printf("\n this is the sizeof sameness : %d \n", sameness);

    struct h_node* h_arr=calloc(sameness,sizeof(h_node));

    /* This is just to check to make sure everything properly prints out */
    printf("The contents of the file are:\n"); 
    for (int i = 0; i < ASCII; i++)
        if(count[i] != 0){
                printf("0x%x happens: %d time(s)\n", i,count[i]);
                h_arr[j].letter = i;
                printf("0x%x \n",h_arr[j].letter);
                h_arr[j].freq = count[i];
                printf("  %d \n",h_arr[j].freq);
                j++;
        }




     struct h_node* h_arr2=calloc(sameness,sizeof(h_node));


    for (int i = 0; i < sameness; i++){
        for (int p = i + 1 ; p < sameness; p++)
            if(h_arr[i].freq > h_arr[i + 1].freq){
                if( i == 0)
                    h_arr2[i] = *createNode(h_arr[i].letter, 
                        h_arr[i].freq,NULL,NULL);
                h_arr2[i]= *createNode(h_arr[i].letter,
                    h_arr[i].freq,&h_arr[i],&h_arr[i+1]);
            }    
            else
               if ( i == 0 )
                   h_arr2[i] = *createNode(h_arr[i + 1].letter, 
                        h_arr[i + 1].freq,NULL,NULL);
                h_arr2[i] = *createNode(h_arr[i].letter, 
                    h_arr[i].freq,&h_arr[i],&h_arr[i]);
        }

     h_sort(h_arr2,sameness); 
    for (int i = 0; i < sameness; i++)
        printf("\n hi %x %d %x %d\n", h_arr2[i].letter, 
            h_arr2[i].freq,h_arr2[i].left -> letter,h_arr2[i].right -> freq); 



    //This will be to input the nodes into a LL //
    for (int i = 0; i < sameness; i++){
       head = insert_ll(&h_arr2[i], &h_arr2[i+1]);
    }

   head = create_tree(head);
   char *codes =(char *) malloc(sizeof(char)); 

   printBin(head,codes,0);


    /* Test to make sure it prints out correctly */
    printf("\n\n");
    printf("this is i: %d\n",i);
    printf("%d\n",size);

    free(arr);
    free(count);

    fclose(fp);
    return 0;
}

1 Ответ

0 голосов
/ 19 октября 2018

Вы вызываете printBin с кодами, указывающими на один символ.Если он повторяет более одного уровня, вы указываете на нераспределенную память.На этом этапе вы перезаписываете что-то важное.Это, вероятно, источник вашей ошибки сегмента.

...