哈夫曼编码解码 C++实现

哈夫曼编码是一个通过哈夫曼树进行的一种编码,一般情况下,以字符:‘0’与‘1’表示。编码的实现过程很简单,只要实现哈夫曼树,通过遍历哈夫曼树,这里我们从每一个叶子结点开始向上遍历,如果该结点为父节点的左孩子,则在字符串后面追加“0”,如果为其右孩子,则在字符串后追加“1”。结束条件为没有父节点。然后将字符串倒过来存入结点中。

C++实现代码如下:

  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4
  5 struct Node
  6 {
  7     double weight;
  8     string ch;
  9     string code;
 10     int lchild, rchild, parent;
 11 };
 12
 13 void Select(Node huffTree[], int *a, int *b, int n)//找权值最小的两个a和b
 14 {
 15     int i;
 16     double weight = 0; //找最小的数
 17     for (i = 0; i <n; i++)
 18     {
 19         if (huffTree[i].parent != -1)     //判断节点是否已经选过
 20             continue;
 21         else
 22         {
 23             if (weight == 0)
 24             {
 25                 weight = huffTree[i].weight;
 26                 *a = i;
 27             }
 28             else
 29             {
 30                 if (huffTree[i].weight < weight)
 31                 {
 32                     weight = huffTree[i].weight;
 33                     *a = i;
 34                 }
 35             }
 36         }
 37     }
 38     weight = 0; //找第二小的数
 39     for (i = 0; i < n; i++)
 40     {
 41         if (huffTree[i].parent != -1 || (i == *a))//排除已选过的数
 42             continue;
 43         else
 44         {
 45             if (weight == 0)
 46             {
 47                 weight = huffTree[i].weight;
 48                 *b = i;
 49             }
 50             else
 51             {
 52                 if (huffTree[i].weight  < weight)
 53                 {
 54                     weight = huffTree[i].weight;
 55                     *b = i;
 56                 }
 57             }
 58         }
 59     }
 60     int temp;
 61     if (huffTree[*a].lchild < huffTree[*b].lchild)  //小的数放左边
 62     {
 63         temp = *a;
 64         *a = *b;
 65         *b = temp;
 66     }
 67 }
 68
 69 void Huff_Tree(Node huffTree[], int w[], string ch[], int n)
 70 {
 71     for (int i = 0; i < 2 * n - 1; i++) //初始过程
 72     {
 73         huffTree[i].parent = -1;
 74         huffTree[i].lchild = -1;
 75         huffTree[i].rchild = -1;
 76         huffTree[i].code = "";
 77     }
 78     for (int i = 0; i < n; i++)
 79     {
 80         huffTree[i].weight = w[i];
 81         huffTree[i].ch = ch[i];
 82     }
 83     for (int k = n; k < 2 * n - 1; k++)
 84     {
 85         int i1 = 0;
 86         int i2 = 0;
 87         Select(huffTree, &i1, &i2, k); //将i1,i2节点合成节点k
 88         huffTree[i1].parent = k;
 89         huffTree[i2].parent = k;
 90         huffTree[k].weight = huffTree[i1].weight + huffTree[i2].weight;
 91         huffTree[k].lchild = i1;
 92         huffTree[k].rchild = i2;
 93     }
 94 }
 95
 96 void Huff_Code(Node huffTree[], int n)
 97 {
 98     int i, j, k;
 99     string s = "";
100     for (i = 0; i < n; i++)
101     {
102         s = "";
103         j = i;
104         while (huffTree[j].parent != -1) //从叶子往上找到根节点
105         {
106             k = huffTree[j].parent;
107             if (j == huffTree[k].lchild) //如果是根的左孩子,则记为0
108             {
109                 s = s + "0";
110             }
111             else
112             {
113                 s = s + "1";
114             }
115             j = huffTree[j].parent;
116         }
117         cout << "字符 " << huffTree[i].ch << " 的编码:";
118         for (int l = s.size() - 1; l >= 0; l--)
119         {
120             cout << s[l];
121             huffTree[i].code += s[l]; //保存编码
122         }
123         cout << endl;
124     }
125 }
126
127 string Huff_Decode(Node huffTree[], int n,string s)
128 {
129     cout << "解码后为:";
130     string temp = "",str="";//保存解码后的字符串
131     for (int i = 0; i < s.size(); i++)
132     {
133         temp = temp + s[i];
134         for (int j = 0; j < n; j++)
135         {
136             if (temp == huffTree[j].code)
137             {
138                 str=str+ huffTree[j].ch;
139                 temp = "";
140                 break;
141             }
142             else if (i == s.size()-1&&j==n-1&&temp!="")//全部遍历后没有
143             {
144                 str= "解码错误!";
145             }
146         }
147     }
148     return str;
149 }
150
151 int main()
152 {
153     //编码过程
154     const int n=5;
155     Node huffTree[2 * n];
156     string str[] = { "A", "B", "C", "D", "E"};
157     int w[] = { 30, 30, 5, 20, 15 };
158     Huff_Tree(huffTree, w, str, n);
159     Huff_Code(huffTree, n);
160     //解码过程
161     string s;
162     cout << "输入编码:";
163     cin >> s;
164     cout << Huff_Decode(huffTree, n, s)<< endl;;
165     system("pause");
166     return 0;
167 }

运行结果如下:

时间: 2024-10-10 17:56:37

哈夫曼编码解码 C++实现的相关文章

加密与压缩,霍夫曼编码解码

简介: 通过统计一篇文章(或一本书)中每个字符出现的频率(比如字母a出现了100次),对文中出现的每个字符进行编码. 这种编码的特点是出现频率越高的字符,其编码长度越短. 有了这样的字符.编码对照表,就可以发"密文"啦! 举个栗子: 早上看到一篇新闻,blablabla内容不重要.如下: Apple Inc. plans to break with its recent pattern of overhauling the design of its flagship iPhone e

哈夫曼(Huffman)树与哈夫曼编码

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4289610.html 哈夫曼树又称最优二叉树,是一种带权路径长最短的树.树的路径长度是从树根到每一个叶子之间的路径长度之和.节点的带树路径长度为从该节点到树根之间的路径长度与该节点权(比如字符在某串中的使用频率)的乘积. 比如有一串字符串如

哈夫曼编码与解码

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> #define MAXNUM 60 typedef struct { char ch; int weight; //权值,这个字符出现的频率 int parent; int left; int right; }HuffNode; typedef struct { char code[MAXNUM]; int st

c++实现哈夫曼树,哈夫曼编码,哈夫曼解码(字符串去重,并统计频率)

#include <iostream> #include <iomanip> #include <string> #include <cstdlib> using namespace std; //定义哈夫曼树存储结构 typedef struct { char data; //存放结点数据 int weight; //记录结点权值 int parent, lchild, rchild; }HTNode, * HuffmanTree; //哈夫曼编码存储表示

哈夫曼树与哈夫曼编码

哈夫曼树与哈夫曼编码 术语: i)路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径. 路径中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. ii)结点的权及带权路径长度 若对树中的每个结点赋给一个有着某种含义的数值,则这个数值称为该结点的权. 结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积. iii)树的带权路径长度 树的带权路径长度:所有叶子结点的带权路径长度之和,记为WPL. 先了解一下

《数据结构复习笔记》--哈夫曼树,哈夫曼编码

先来了解一下哈夫曼树. 带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值 wk,从根结点到每个叶子结点的长度为 lk,则每个叶子结点的带权路径长度之和就是: 最优二叉树或哈夫曼树: WPL最小的二叉树. [例]有五个叶子结点,它们的权值为{1,2,3,4,5},用此权值序列可以构造出形状不同的多个二叉树. 其中结果wpl最小值的是:33=(1+2)*3+(3)*2+(4+5)*2: 哈夫曼树的构造: 每次把权值最小的两棵二叉树合并, 代码: typedef struct Tr

C语言之霍夫曼编码学习

?1,霍夫曼编码描述哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩.这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码.这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目

哈夫曼编码(Huffman coding)的那些事,(编码技术介绍和程序实现)

前言 哈夫曼编码(Huffman coding)是一种可变长的前缀码.哈夫曼编码使用的算法是David A. Huffman还是在MIT的学生时提出的,并且在1952年发表了名为<A Method for the Construction of Minimum-Redundancy Codes>的文章.编码这种编码的过程叫做哈夫曼编码,它是一种普遍的熵编码技术,包括用于无损数据压缩领域.由于哈夫曼编码的运用广泛,本文将简要介绍: 哈夫曼编码的编码(不包含解码)原理 代码(java)实现过程 一

机智零崎不会没梗Ⅱ (哈夫曼编码、优先队列)

题目描述 你满心欢喜的召唤出了外星生物,以为可以变身超人拥有强大力量战胜一切怪兽,然而面对着身前高大的外星生物你一脸茫然,因为,你懂M78星云语吗?不过不用担心,因为零崎非常机智,他给出了关键性的提示:“讲道理,日语可是全宇宙通用语,所以为什么不试试和外星人讲日语呢?” 不过现在外星生物说的话都是“[email protected]#$%^&%#%I&!……”这样的东西,你要怎么转换成日语呢? 作位全宇宙通用的日语,自然有一套万能的转换算法,那就是Huffman编码转换!当然了这肯定不是普