symbol* new_node(symbol *n1,symbol *n2){ /* new_node() - given two symbols from the symbol table-tree, combines them into one Internal Node and then returns a pointer to the new internal node. */ // Init symbol *s; s=init_symbol(INTERNAL_NODE); // Set left and right children s->left=n1; s->right=n2; // Set parents of children n1->parent=s; n2->parent=s; // Set frequency s->frequency = n1->frequency + n2->frequency; return s; }
symbol* add_symbol_to_table (char* buffer, int size) { symbol* sym = NULL; #ifdef DEBUG printf ("adding symbol with buffer: %s\n", buffer); #endif // Find or create the symbol as needed if (symbols->size > 0) { sym = get_symbol(buffer); } if (sym == NULL) { // Symbol wasn't found // Actually create the symbol from the buffer sym = init_symbol(); set_symbol_name(sym, buffer, size); } else { // Don't need to update table, return early since sym has been found return sym; } // Adjust the symbolTable pointers if (symbols->size == 0) { symbols->first = sym; symbols->last = sym; } else { symbols->last->next = sym; // Point the previous last's next to the new last sym->prev = symbols->last; symbols->last = sym; } symbols->size++; return sym; }
void update_frequency(symbol *r, int c){ /* update_frequency() - given the root of a symbol table-tree and a character, increases the frequency of that character in the symbol table-tree, creating nodes as necessary. */ symbol *s; if (!exists_symbol(r,c)) s=init_symbol(c); else s=remove_symbol(r,c); s->frequency++; insert_symbol(r,s); }
int main(int argc, char *argv[]){ // 1. Initialization int c; symbol *root; root=init_symbol(ROOT_NODE); root->frequency=NON_EXISTENT; root->parent=root; // 1.a. init: file pointers FILE *inputfile; FILE *outputfile; inputfile=NULL; outputfile=NULL; if (argc >=2) inputfile = fopen(argv[1],"r"); if (argc >=3) outputfile = fopen(argv[2],"w"); if (inputfile == NULL) { fprintf(stderr, "Can't open input file. \n"); exit(1); } if (outputfile == NULL) { outputfile=stdout; } // 2. count the frequency of each character in inputfile while((c=fgetc(inputfile))!=EOF){ update_frequency(root,c); } update_frequency(root,-1); // 3. Make the huffman tree while(count_parentless_nodes(root) > 1){ symbol *node1,*node2, *newnode; node1 = get_rarest_parentless_node(root); node1->parent=node1; //temporarily node2 = get_rarest_parentless_node(root); node2->parent=node2; //temporarily newnode = new_node(node1, node2); insert_symbol(root,newnode); } // 4. Output symbol mappings for(c=-1;c<256;c++){ char *encodingstring; encodingstring=get_encoding(root,c); int freq=get_frequency(root,c); if (freq > 0){ /*if (c <=127 && c>=32 ) fprintf(outputfile,"%c\t%d\t%s\n", c, freq, encodingstring); else */ fprintf(outputfile,"%d\t%d\t%s\n", c, freq, encodingstring); } free(encodingstring); } fprintf(outputfile,"\n"); // 5. Output encoding of inputfile rewind(inputfile); while((c=fgetc(inputfile))!=EOF){ char *encodingstring; encodingstring=get_encoding(root,c); fprintf(outputfile, "%s", encodingstring); free(encodingstring); } char *encodingstring; encodingstring=get_encoding(root,EOF); fprintf(outputfile, "%s", encodingstring); free(encodingstring); fprintf(outputfile,"\n"); free_symbol(root); // 6. Close file pointers fclose(inputfile); fclose(outputfile); }