赫夫曼编码
来源:互联网 发布:免费空间域名 编辑:程序博客网 时间:2024/04/30 06:24
ACM模版
赫夫曼编码
main
main.cpp
#include <iostream>#include "huffman.hpp"int main(int argc, const char * argv[]){ // 源码 char S[] = "I love Golden Dream!";// char S[] = "I love FishC.com!"; // 压缩码 char s[] = "01101101001111111001011100111111110000001010010110010011101101000100110101";// char s[] = "100011001110010000101011010010100000101011111011111101100101101110"; // 构建赫夫曼树 htTree *codeTree = buildTree(S); // 构建变长前缀码表 hlTable *codeTable = buildTable(codeTree); // 压缩 encode(codeTable, S); // 解压 decode(codeTree, s); return 0;}
queue
queue.hpp
#ifndef queue_hpp#define queue_hpp#include <stdio.h>#include "huffman.hpp"#define TYPE htNode *#define MAX_SZ 256typedef struct _pQueueNode // 队列结点{ TYPE val; unsigned int priority; struct _pQueueNode *next;}pQueueNode;typedef struct _pQueue // 队列{ unsigned int size; pQueueNode *first;}pQueue;void initPQueue(pQueue **queue); // 初始化队列void addPQueue(pQueue **queue, TYPE val, unsigned int priority); // 插入队列头结点TYPE getPQueue(pQueue **queue); // 获取队列头结点#endif /* queue_hpp */
queue.cpp
#include "queue.hpp"#include <stdlib.h>// 初始化队列void initPQueue(pQueue **queue){ (*queue) = (pQueue *)malloc(sizeof(pQueue)); (*queue)->first = NULL; (*queue)->size = 0; return ;}// 将出现的字符逐个插入队列,并维护出现次数是从小到大void addPQueue(pQueue **queue, TYPE val, unsigned int priority){ if ((*queue)->size == MAX_SZ) { printf("\nQueue is full.\n"); return ; } pQueueNode *aux = (pQueueNode *)malloc(sizeof(pQueueNode)); aux->priority = priority; aux->val = val; if ((*queue)->size == 0 || (*queue)->first == NULL) { aux->next = NULL; (*queue)->first = aux; (*queue)->size = 1; return ; } else { // 小于头则插入头 if (priority <= (*queue)->first->priority) { aux->next = (*queue)->first; (*queue)->first = aux; (*queue)->size++; return ; } else { pQueueNode *iterator = (*queue)->first; // 迭代器 // 插入合适的位置,维护从小到大顺序 while (iterator->next != NULL) { if (priority <= iterator->next->priority) { aux->next = iterator->next; iterator->next = aux; (*queue)->size++; return ; } iterator = iterator->next; } // 当大于队列内所有值,则插入队尾 if (iterator->next == NULL) { aux->next = NULL; iterator->next = aux; (*queue)->size++; return ; } } }}// 从队列头逐个取出(越接近头部出现的次数越少)TYPE getPQueue(pQueue **queue){ TYPE returnValue; if ((*queue)->size > 0) { returnValue = (*queue)->first->val; (*queue)->first = (*queue)->first->next; (*queue)->size--; } else { printf("\nQueue is empty.\n"); } return returnValue;}
huffman
huffman.hpp
#ifndef huffman_hpp#define huffman_hpp#include <stdio.h>typedef struct _htNode // 树结点{ char symbol; struct _htNode *left, *right;}htNode;typedef struct _htTree // 树{ htNode *root;}htTree;typedef struct _hlNode // 表结点{ char symbol; char *code; struct _hlNode *next;}hlNode;typedef struct _hlTable // 表{ hlNode *first; hlNode *last;}hlTable;htTree *buildTree(char *inputString); // 构建赫夫曼树hlTable *buildTable(htTree *huffmanTree); // 构建变长前缀码表void encode(hlTable *table, char *stringToEncode); // 压缩void decode(htTree *tree, char *stringToDecode); // 解压#endif /* huffman_hpp */
huffman.cpp
#include "huffman.hpp"#include "queue.hpp"#include <string>#include <stdlib.h>// 创建赫夫曼树htTree *buildTree(char *inputString){ int *probability = (int *)malloc(sizeof(int) * 256); // 存放ASCII自定义对应的字符 // 初始化 for (int i = 0; i < 256; i++) { probability[i] = 0; } // 统计待编码的字符串各个字符出现的次数 for (int j = 0; inputString[j] != '\0'; j++) { probability[(unsigned char)inputString[j]]++; // 此处强制转换可有可无 } // pQueue队列的头指针 pQueue *huffmanQueue; initPQueue(&huffmanQueue); // 填充队列 for (int k = 0; k < 256; k++) { if (probability[k] != 0) { htNode *aux = (htNode *)malloc(sizeof(htNode)); aux->left = NULL; aux->right = NULL; aux->symbol = (char)k; addPQueue(&huffmanQueue, aux, probability[k]); } } free(probability); //插入完毕,释放无用内存 // 生成赫夫曼树 while (huffmanQueue->size != 1) { int priority = huffmanQueue->first->priority; priority += huffmanQueue->first->next->priority; htNode *left = getPQueue(&huffmanQueue); htNode *right = getPQueue(&huffmanQueue); htNode *newNode = (htNode *)malloc(sizeof(htNode)); newNode->left = left; newNode->right = right; addPQueue(&huffmanQueue, newNode, priority); } htTree *tree = (htTree *)malloc(sizeof(htTree)); tree->root = getPQueue(&huffmanQueue); // 赫夫曼树根结点 return tree; // 返回赫夫曼树}// 生成前缀码void traverseTree(htNode *treeNode, hlTable ** table, int k, char code[256]){ if (treeNode->left == NULL && treeNode->right == NULL) // 存储前缀码 { code[k] = '\0'; hlNode *aux = (hlNode *)malloc(sizeof(hlNode)); aux->code = (char *)malloc(sizeof(char) * (strlen(code) + 1)); strcpy(aux->code, code); aux->symbol = treeNode->symbol; aux->next = NULL; if ((*table)->first == NULL) { (*table)->first = aux; (*table)->last = aux; } else { (*table)->last->next = aux; (*table)->last = aux; } } if (treeNode->left != NULL) // 如果左孩子不为空,则前缀码填'0' { code[k] = '0'; traverseTree(treeNode->left, table, k + 1, code); } if (treeNode->right != NULL) // 如果右孩子不为空,则前缀码填'1' { code[k] = '1'; traverseTree(treeNode->right, table, k + 1, code); } return ;}// 构建变长前缀码表hlTable *buildTable(htTree *huffmanTree){ hlTable *table = (hlTable *)malloc(sizeof(hlTable)); table->first = NULL; table->last = NULL; char code[256]; int k = 0; traverseTree(huffmanTree->root, &table, k, code); return table; // 返回变长前缀码表}// 压缩void encode(hlTable *table, char *stringToEncode){ hlNode *traversal; printf("Encoding......\nInput string:\n%s\nEncoded string:\n", stringToEncode); for (int i = 0; stringToEncode[i] != '\0'; i++) { traversal = table->first; while (traversal->symbol != stringToEncode[i]) { traversal = traversal->next; } printf("%s", traversal->code); } printf("\n"); return ;}// 解压void decode(htTree *tree, char *stringToDecode){ htNode *traversal = tree->root; printf("\nDecoding......\nInput string:\n%s\nDecoded string:\n", stringToDecode); for (int i = 0; stringToDecode[i] != '\0'; i++) { if (traversal->left == NULL && traversal->right == NULL) { printf("%c", traversal->symbol); traversal = tree->root; } if (stringToDecode[i] == '0') // 等于'0'向左孩子查找 { traversal = traversal->left; } else /* if (stringToDecode[i] == '1')等于'1'向右孩子查找 */ { traversal = traversal->right; } } if (traversal->left == NULL && traversal->right == NULL) { printf("%c", traversal->symbol); } putchar('\n'); return ;}
1 0
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码!
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- Jagsaw文档
- eclipse安装web插件、安装centos版本的idea
- FragmentTabHost中如何实现状态保存
- Linux命令常用
- js闭包
- 赫夫曼编码
- UGUI Scrollrect滚动优化:无限循环利用
- js工厂方法模式
- C语言 文件映射
- LWIP 实现DNS域名解析
- 414 - Machined Surfaces
- eclipse 页面字符编码
- ASP.NET Page Life Cycle Events
- LintCode Consistent Hashing(一致性哈希算法)