[Sonia] Implementation of Huffman Algorithm
2013-03-04 21:44
316 查看
首次使用自顶向下的方法进行编程,初步感受到了增量式编码与调试的优点,能独立解决编程过程中出现的各种Bug。 进步明显且迅速,特此表扬,(*^__^*) ……
//File name: h_tree.h #ifndef _H_TREE_H_ #define _H_TREE_H_ #define MAX_NODES 100 #define MAX_CODE_LEN 100 #define MAX_SYMBOL_LEN 100 //#define DEBUG #include <stdio.h> #include <stdlib.h> #include <string.h> struct h_tree{ int freq; int code; h_tree* next; h_tree* left; h_tree* right; h_tree* father; }; struct code_node{ int start; int code[MAX_CODE_LEN]; }; struct symbol_node{ char symbol[MAX_SYMBOL_LEN]; int freq; h_tree* node; }; int read_data(char* file_name_in, struct symbol_node* nodes[], int* length); struct h_tree* init_symbol_set(struct symbol_node* nodes[]); struct h_tree* create_htree(struct h_tree* symbol_set); int huf_code(struct symbol_node* nodes[], struct h_tree* root, char* file_name_out, int length); void free_htree(struct h_tree* root); struct h_tree* make_tree(int freq); struct h_tree* insert(struct h_tree* node, struct h_tree* head); int write_file(FILE* fp, struct symbol_node* nodes,struct code_node* code, int length); struct code_node* make_code(); #ifdef DEBUG void print_symbol_node(struct symbol_node* p); void print_symbol_set(struct h_tree* head); #endif #endif
// File name: h_tree.cpp #include "h_tree.h" int read_data(char* file_name, struct symbol_node* nodes[], int* length) { int i = 0; int freq = 0; FILE* fp = NULL; struct h_tree* p = NULL; char symbol[MAX_SYMBOL_LEN] = {0}; (*length) = 0; //初始化节点的长度 if((fp = fopen(file_name, "r")) == NULL) //打开文件 { printf("Can not open the file!\n"); exit(-1); } while(!feof(fp) && i < MAX_NODES) //读取symbol和freq数据 { fscanf(fp, "%s", symbol); fscanf(fp, "%d", &freq); nodes[i] = (struct symbol_node*) malloc(sizeof(struct symbol_node)); if(nodes[i] == NULL) { printf("Allocation fails!"); exit(-1); } strcpy(nodes[i]->symbol, symbol); nodes[i]->freq = freq; nodes[i]->node = NULL; i++; } if(!feof(fp)) //若文件未达到文件尾,即MAX_SYMBOL_LEN设置过小,数组溢出 { printf("Too many symbols in the file. Please adjust the value of MAX_SYMBOL_LEN !\n"); exit(-1); } (*length) = i; //记录节点的个数 fclose(fp); return 0; } struct h_tree* init_symbol_set(struct symbol_node* nodes[]) //初始化符号集合 { int i = 0; struct h_tree* head = NULL; struct h_tree* node = NULL; head = make_tree(0); //新建一个空的头结点 while(nodes[i] != NULL) { node = make_tree(nodes[i]->freq); nodes[i]->node = node; //将该h_tree节点指针存回nodes[i]中 以便后续从叶子节点查找哈夫曼编码 head = insert(node, head); //按照freq从小到大的顺序排成有序链表 i++; } return head; } struct h_tree* insert(struct h_tree* node, struct h_tree* head) //插入排序 { struct h_tree* p = NULL; struct h_tree* p_pre = NULL; if(head->next == NULL) { head->next = node; return head; } p = head->next; p_pre = head; while(p != NULL) { if(node->freq > p->freq) { p_pre = p; p = p->next; } else break; } if(p == NULL) p_pre->next = node; else { p_pre->next = node; node->next = p; } return head; } struct h_tree* make_tree(int freq) { h_tree* node = NULL; node = (struct h_tree *) malloc(sizeof(struct h_tree)); if(node == NULL) { printf("Allocation fails!"); exit(-1); } node->code = -1; node->father = node->left = node->next = node->right = NULL; node->freq = freq; return node; } struct h_tree* create_htree(struct h_tree* symbol_set) { struct h_tree* p = NULL; struct h_tree* q = NULL; struct h_tree* node = NULL; struct h_tree* root = NULL; struct h_tree* head = symbol_set; while(head->next->next != NULL) { p = head->next; //Get-min head->next = p->next; p->next =NULL; //Delete p q = head->next; //Get-min head->next = q->next; q->next = NULL; //Delete q root = node = make_tree(p->freq + q->freq); //new h_tree node root->left = p; // root->right = q; p->father = root; q->father = root; p->code = 0; q->code = 1; head = insert(node, head); #ifdef DEBUG print_symbol_set(head); #endif } return root; } int huf_code(struct symbol_node* nodes[], struct h_tree* root, char* file_name_out, int length) { int i = 0; struct code_node* code[MAX_SYMBOL_LEN] = {NULL}; struct h_tree* p = NULL; FILE* fp = NULL; if(root == NULL) { printf("The h_tree is empty!\n"); exit(-1); } if((fp = fopen(file_name_out, "w")) == NULL) { printf("Can not open the file!\n"); exit(-1); } for(i = 0; i < length; i++) { code[i] = make_code(); //新建code节点 p = nodes[i]->node; //p指向叶子节点 while(p != root) { code[i]->start = code[i]->start - 1; if(code[i]->start >= 0) { code[i]->code[code[i]->start]= p->code; p = p->father; } else //编码的数量过多 数组溢出 { printf("Too many codes! Please adjust the value of MAX_CODE_LEN !\n"); exit(-1); } } write_file(fp, nodes[i],code[i], length); //将原字符串和编码写入新文件 } fclose(fp); return 0; } int write_file(FILE* fp, struct symbol_node* node, struct code_node* code, int length) { int i = 0; if(fp == NULL) { printf("File open error!\n"); exit(-1); } fprintf(fp, "%s ", node->symbol); //写入字符串 for(i = code->start; i < MAX_CODE_LEN; i++) //写入编码 fprintf(fp, "%d ", (code->code)[i]); fprintf(fp, "\n"); return 0; } struct code_node* make_code() { int i = 0; struct code_node* node = NULL; node = (struct code_node*) malloc(sizeof(struct code_node)); if(node == NULL) { printf("Allocation fails!"); exit(-1); } node->start = MAX_CODE_LEN; for(i = 0; i < MAX_CODE_LEN; i++) (node->code)[i] = -1; //初始化code值为-1 return node; } void free_htree(struct h_tree* root) { struct h_tree* p = NULL; if(root != NULL) { p = root; if(p->left != NULL) free_htree(p->left); if(p->right != NULL) free_htree(p->right); free(p); } } #ifdef DEBUG void print_symbol_node(struct symbol_node* p) { if( p != NULL) { printf("\nsym = %10s, freq = %d", p->symbol, p->freq); } } void print_symbol_set(struct h_tree* head) { struct h_tree* p = head->next; while(p != NULL) { printf("\n@freq = %d", p->freq); p = p->next; } } #endif
// File name: main.cpp #include "h_tree.h" int main() { int length = 0; char file_name_in[100] = "data.txt"; char file_name_out[100] = "code.txt"; struct h_tree* root= NULL; struct h_tree* symbol_set= NULL; struct symbol_node* nodes[MAX_NODES] = {NULL}; read_data(file_name_in, nodes, &length); //读取数据 #ifdef DEBUG for(int i =0; i < length; i++) { print_symbol_node(nodes[i]); } #endif symbol_set = init_symbol_set(nodes); #ifdef DEBUG print_symbol_set(symbol_set); #endif root = create_htree(symbol_set); //建立哈夫曼树 huf_code(nodes, root, file_name_out, length); //哈夫曼编码 free_htree(root); //释放内存空间 return 0; }
相关文章推荐
- 论文笔记:Research and Implementation of a Multi-label Learning Algorithm for Chinese Text Classification
- Implementation codes of Data Structures and Algorithm Analysis in C (1)
- Implementation of Strassen’s Algorithm for Matrix Multiplication
- [Sonia] Implementation of a Binary Tree Sort in C
- Algorithm: The implementation of Trie Tree (C++)
- A Fast Priority Queue Implementation of the Dijkstra Shortest Path Algorithm
- Rob Hess's C implementation of SIFT algorithm
- Algorithm: The implementation of Trie Tree (C++)
- Implementation Of TDOA Using Chan Algorithm And Taylor Algorithm
- 《A Sub-Pixel Edge Detector: an Implementation of the Canny/Devernay Algorithm》
- implementation of General Sort Algorithm - mark
- An implementation of the skip list data structure written in C++
- Design and Implementation of the Sun Network File System
- the implementation of system call in linux
- Backpropagation Algorithm Implementation
- VC ++中添加了一个新类后cannot find the definition (implementation) of this function
- Optimization of BackTracking algorithm for n queen problem
- Princeton Algorithms: Part 1 [week 1:Analysis of Algorithms]
- Algorithm: Sieve of Eratosthenes
- Implementation and Applications of DSL Technology