Haffman算法(C++)

Huffman编码,C++实现,只是为了说明大致的思路,还有很多不完美之处,比如在输入数据超出限制等条件下会出现错误。

  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4 #define MAX 20
  5
  6 /*
  7 ** 用二叉树表示的Huffman节点
  8 */
  9 typedef struct NodeTag {
 10     char c;                     // 字母
 11     int weight;                 // 频率
 12     string code;                // 编码后的字符串
 13     struct NodeTag * lchild;    // 左孩子
 14     struct NodeTag * rchild;    // 右孩子
 15 } Node;
 16
 17
 18 class Container {
 19
 20     private:
 21         Node *nodes[MAX];       // 保存各节点指针的数组
 22         int size;               // 节点的个数
 23
 24     public:
 25         Container () {
 26             size = 0;
 27             for ( int i = 0; i < MAX; i++ ) {
 28                 nodes[i] = NULL;
 29             }
 30         }
 31
 32         /*
 33         ** 采用插入排序的方法,将节点node加入到数组nodes中,按照weight从小到大排列
 34         */
 35         void push ( Node *node ) {
 36             int weight = node->weight;
 37             int i = size-1;
 38             while ( i >= 0 && weight > nodes[i]->weight ) {
 39                 nodes[i+1] = nodes[i];
 40                 i--;
 41             }
 42             nodes[i+1] = node;
 43             size++;
 44         }
 45
 46         /*
 47         ** 返回weight值最小的一个节点
 48         */
 49         Node * pop () {
 50             Node *node = nodes[size-1];
 51             size--;
 52             return node;
 53         }
 54
 55         /*
 56         ** 返回当前的节点数目
 57         */
 58         int getSize() {
 59             return size;
 60         }
 61
 62 };
 63
 64 /*
 65 ** 对所有的叶子节点进行编码,得到各字母的码表
 66 ** root:指向根节点的指针;code:本节点的编码
 67 */
 68 int huffmanCode( Node *root, const string code ) {
 69
 70     root->code = code;
 71     string temp;
 72
 73     if( root != NULL ){
 74
 75         // 叶子节点,则输出编码方式
 76         if( root->rchild == NULL && root->lchild == NULL ) {
 77             cout<<root->c<<":"<<root->weight<<" "<<root->code<<endl;
 78         } else {
 79             temp = code;
 80             huffmanCode ( root->lchild, temp.append("0") );   // 会增加上去,不用重新赋值
 81             temp = code;
 82             huffmanCode ( root->rchild, temp.append("1") );
 83         }
 84
 85     }
 86
 87     return 0;
 88
 89 }
 90
 91 /*
 92 ** Huffman编码的函数
 93 ** letter:字母表;weight:各字母的频率;length:字母的总个数
 94 */
 95 void haffman ( char letter[], int weight[], int length ) {
 96
 97     Node *node = NULL;
 98     Node *first = NULL;
 99     Node *second = NULL;
100     Container *obj = NULL;
101
102     obj = new Container();
103
104     for ( int i = 0; i < length; i++ ) {
105         /*
106         ** 创建一个新节点node,节点字符为c[i],频率为weight[i],左右孩子都为Null;
107         ** 将node按从小到大的顺序加入到容器obj中;
108         */
109         node = new Node();
110         node->c = letter[i];
111         node->weight = weight[i];
112         node->lchild = NULL;
113         node->rchild = NULL;
114         obj->push(node);
115     }
116
117     cout<<"All nodes are pushed into the queue:"<<obj->getSize()<<endl;
118
119     /*
120     ** 当容器中只有一个元素时,该元素即为指向Huffman编码二叉树的根节点的指针
121     */
122     while ( obj->getSize() > 1 ) {
123         /*
124         ** 选出最小的两个元素,创建一个新的父节点,频率为两者之和,将父节点加入到队列中;
125         */
126         first = obj->pop();
127         second = obj->pop();
128         node = new Node();
129         node->weight = first->weight + second->weight;   // 非根节点的字母不重要,故不用赋值
130         node->lchild = first;
131         node->rchild = second;
132         obj->push(node);
133     }
134
135     cout<<"After the Haffman code:"<<obj->getSize()<<endl;
136
137     /*
138     ** 采用中根次序遍历方法对二叉树进行遍历,得到每个叶子节点的编码
139     */
140     node = obj->pop();
141     cout<<node->weight<<endl;
142     huffmanCode( node, "");
143
144 }
145
146 int main () {
147     char letter[] = {‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ‘h‘};
148     int weight[] = {1, 1, 2, 3, 5, 8, 13, 21};
149     int length = 8;
150     haffman( letter, weight, length );
151     return 0;
152 }
时间: 2024-10-25 15:04:07

Haffman算法(C++)的相关文章

压缩算法

来源:http://www.oschina.net/question/16_2639 再学习了haffman算法之后发现压缩算法很有意思,上网查了点资料,这是做好的一篇(主要是我能理解).前面几种都能看懂,关键是那个LZ77算法.这个是很强大的压缩算法,zip,rar用得都是这种算法,让我们来感叹下两个犹太人的强大!!! 几个常见的压缩算法(转)(一) 字典算法字典算法是最为简单的压缩算法之一.它是把文本中出现频率比较多的单词或词汇组合做成一个对应的字典列表,并用特殊代码来表示这个单词或词汇.例

JPEG编码(二)

来自CSDN评论区http://bbs.csdn.net/topics/190980 1. 色彩模型 JPEG 的图片使用的是 YCrCb 颜色模型, 而不是计算机上最常用的 RGB. 关于色彩模型, 这里不多阐述. 只是说明, YCrCb 模型更适合图形压缩. 因为人眼对图片上的亮度 Y 的变化远比色度 C 的变化敏感. 我们完全可以每个点保存一个 8bit 的亮度值, 每 2x2 个点保存一个 Cr Cb 值, 而图象在肉眼中的感觉不会起太大的变化. 所以, 原来用 RGB 模型, 4 个点

哈夫曼算法(haffman)实现压缩和解压缩-C语言实现

/* * ===================================================================================== * * Filename: haffman.c * * Description: huffman coder decoder * * Version: 1.0 * Created: * Revision: none * Compiler: gcc * * * =============================

数据结构与算法总结

一:绪论 表示时间复杂度的阶有: O(1) :常量时间阶 O (n):线性时间阶 O(㏒n) :对数时间阶 O(n㏒n) :线性对数时间阶 O (nk): k≥2 ,k次方时间阶 以下六种计算算法时间的多项式是最常用的.其关系为: O(1)<O(㏒n)<O(n)<O(n㏒n)<O(n2)<O(n3) 指数时间的关系为: O(2n)<O(n!)<O(nn) 算法的空间复杂度定义为:S(n) = O(g(n)) 表示随着问题规模 n 的增大,算法运行所需存储量S(n)

haffman哈夫曼编码的实现

<span style="font-size:18px;">/* 1.在一棵二叉树中,我们定义从A节点到B节点所经过的分支序列为从A节点到B节点的路径: 定义从A节点到B节点所经过的分支个数为从A节点到B节点的路径长度: 定义从二叉树的根节点到二叉树中所有叶节点的路径长度之和为该二叉树的路径长度. 2.如果二叉树中的叶节点都带有权值,则可以把这个定义推广.设二叉树有n歌带权值的叶节点,定义从二叉树的 根节点到二叉树中所有叶节点的路径长度与相应叶节点权值的乘积之和为该二叉树的

基于哈夫曼(haffuman)算法的文件压缩的实现(C语言)(转)

本文首先简要阐述哈夫曼算法的基本思想,然后介绍了使用哈夫曼算法进行文件压缩和解压缩的 处理步骤,最后给出了C语言实现的文件压缩和解压缩的源代码. 哈夫曼算法的主要思想是: ①首先遍历要处理的字符串,得到每个字符的出现的次数: ②将每个字符(以其出现次数为权值)分别构造为二叉树(注意此时的二叉树只有一个节点): ③取所有二叉树种种字符出现次数最小的二叉树合并为一颗新的二叉树,新二叉树根节点 的权值等于两个子节点的权值之和,新节点中的字符忽略: ④重复过程③直到所有树被合并为同一棵二叉树 ⑤遍历最后

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

基于位置信息的聚类算法介绍及模型选择

百度百科 聚类:将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类.由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异."物以类聚,人以群分",在自然科学和社会科学中,存在着大量的分类问题.聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法.聚类分析起源于分类学,但是聚类不等于分类.聚类与分类的不同在于,聚类所要求划分的类是未知的. 分类和聚类算法一直以来都是数据挖掘,机器学习领域的热门课题,因此产生了众多的