Huffman
来源:互联网 发布:中国是否允许持枪知乎 编辑:程序博客网 时间:2024/05/17 07:36
Huffman算法
霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现概率的方法得到的,出现概率高的字母使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
来自文库
演算过程
(一)进行霍夫曼编码前,我们先创建一个霍夫曼树。
⒈将每个英文字母依照出现频率由小排到大,最小在左.
⒉每个字母都代表一个终端节点(叶节点),比较F.O.R.G.E.T六个字母中每个字母的出现频率,将最小的两个字母频率相加合成一个新的节点。如Fig.2所示,发现F与O的频率最小,故相加2+3=5。
⒊比较5.R.G.E.T,发现R与G的频率最小,故相加4+4=8。
⒋比较5.8.E.T,发现5与E的频率最小,故相加5+5=10。
⒌比较8.10.T,发现8与T的频率最小,故相加8+7=15。
⒍最后剩10.15,没有可以比较的对象,相加10+15=25。
最后产生的树状图就是霍夫曼树
(二)进行编码
1.给霍夫曼树的所有左链接’0’与右链接’1’。
2.从树根至树叶依序记录所有字母的编码
在这里, 我们主程序其实是排序, 我选用的是堆排序, 因为用起来方便, 不需要每次新开辟空间 代码稍微有点变化
每次将最小的放在第一个, 将第一保存后再放在最后, 然后数组大小 -1;
//排序, 使用的是堆排序void sort(int first, int last){ int i = first * 2 + 1; node tmp = arr[first]; for (; i < last; first = i, i = i * 2 + 1) { if (i < last - 1 && arr[i].num > arr[i + 1].num) i++; if (arr[first].num > arr[i].num) arr[first] = arr[i]; else break; } arr[first] = tmp;}//交换, 堆排序里的必要步骤, 将第一个位置与最后一个位置的进行交换void Swap(int i, int j){ node tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;}//进行sort 和 SwapT sort_min(int &size_arr){ //L : 存储arr[0]的链表 T L = new Node; *L = arr[0]; Swap(0, size_arr - 1); sort(0, size_arr - 2); size_arr--; return L;}
源代码
#include <stdlib.h>#include <stdio.h>typedef int Type;struct Node;typedef struct Node *T;typedef struct Node node;struct Node{ Type num; T Left; T Right; Node() : Left(NULL), Right(NULL) {}};void Swap(int i, int j);void sort(int first, int last);T sort_min(int &size_arr);void Create(int a[], int size);void Add(T L, T R, int size_arr);void Print(T Huff);int main(){ int a[] = { 10, 15, 13, 12, 3, 4, 1 }; int size_arr = sizeof(a) / sizeof(a[0]); Create(a, size_arr); system("pause"); return 0;}//arr是 Node 的数组;node *arr;//排序, 使用的是堆排序void sort(int first, int last){ int i = first * 2 + 1; node tmp = arr[first]; for (; i < last; first = i, i = i * 2 + 1) { if (i < last - 1 && arr[i].num > arr[i + 1].num) i++; if (arr[first].num > arr[i].num) arr[first] = arr[i]; else break; } arr[first] = tmp;}//交换, 堆排序里的必要步骤, 将第一个位置与最后一个位置的进行交换void Swap(int i, int j){ node tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;}//进行sort 和 SwapT sort_min(int &size_arr){ //L : 存储arr[0]的链表 T L = new Node; *L = arr[0]; Swap(0, size_arr - 1); sort(0, size_arr - 2); size_arr--; return L;}//将两个最小的数相加, 得到新的链表void Add(T L, T R, int size_arr){ T tmp = new Node; tmp->num = L->num + R->num; tmp->Left = L; tmp->Right = R; arr[size_arr - 1] = *tmp;}//执行所有功能void Create(int a[], int size){ //size_arr : 数组的大小; int size_arr; size_arr = size; //初始化arr; arr = (T)malloc(sizeof(node) * size); for (int i = 0; i < size; i++) { arr[i].num = a[i]; arr[i].Left = arr[i].Right = NULL; } //L : 左节点; //R : 右节点; T L = new Node, R = new Node; for (int i = 0; i < size - 1; i++) { //堆排序 for (int j = size_arr / 2; j >= 0; j--) sort(i, size_arr); L = sort_min(size_arr); R = sort_min(size_arr); size_arr++; Add(L, R, size_arr); } T Huff = new Node; *Huff = arr[0]; Print(Huff); /* 当然也可以直接传 &arr[0]的地址; */}void Print(T Huff){ if (Huff != NULL) { printf("%d ", Huff->num); Print(Huff->Left); Print(Huff->Right); }}
阅读全文
0 0
- Huffman
- Huffman
- huffman
- huffman
- Huffman
- Huffman
- huffman
- huffman
- Huffman
- huffman
- Huffman
- Huffman
- Huffman
- Huffman树&&Huffman编码
- Huffman&Morse
- huffman编码
- huffman编码
- HUFFMAN 编码
- TCP 三次握手 与 四次分手
- 基于UDP广播的回射服务器
- C++继承详解:共有(public)继承,私有(private)继承,保护(protected)继承
- CSDN-markdown编辑器模板
- CSS3 DIV自适应宽度、水平居中的实现方法
- Huffman
- Django REST Framework(一) 初步使用
- Cygwin安装及Cmdstan-2.16.0在Cygwin下的使用
- 弹出呼叫电话号码
- (Kattis
- 广播中的信号引起的竞争状态
- js实现的哈夫曼编码
- ccf csp认证中间数java代码
- tcp 与 udp