数据结构(六)霍夫曼树与编码
2018-02-02 16:07
169 查看
1、算法流程
(1)构建霍夫曼树:自底向上
根据统计频率构建霍夫曼树: A、把所有的节点扔进排序队列queue中; B、从queue选择选择前面两个最小的元素a、b,把最小的树a作为左节点,把最小的b作为右节点,以此构建父节点c(c的频率值为a+b的频率值),然后把a、b从队列删除、把c节点插入队列; C、循环(A)、(B)步骤构建霍夫曼树,直到queue为空。
(2)编码阶段:自顶向下
A、除了树的根节点没有码值之外,其他的根据左右子节点进行编码,做节点编码为0,右节点编码为1;
B、子节点在父节点码值的基础上,在后面加上一位对应的码值。
(3)解码阶段:自顶向下解码
根据给定的码值,从树根开始递归遍历,遇到0向左走,遇到1向又走,直到码值为空或者遇到叶子节点返回。
2、代码实现
#ifndef DATA_STRUCT_TREE_H
#define DATA_STRUCT_TREE_H
#include<vector>
#include <set>
#include <queue>
#include <string>
using namespace std;
class node{
public:
node(){
left_child=NULL;
right_child=NULL;
frequency=0;
coding.clear();
words="";
};
~node(){};
node* left_child;
node* right_child;
int frequency;
std::vector<bool> coding;
string words;
public:
bool operator <(const node& n1) const
{
return frequency<n1.frequency;
}
};
class huffman_coding{
public:
static void create_tree(std::set<node>&queue,std::vector<node*>&tree){
while (!queue.empty())
{
node *left= new node(*queue.begin());
queue.erase(queue.begin());
tree.push_back(left);
if (!queue.empty())
{
node *right=new node(*queue.begin());
queue.erase(*queue.begin());
tree.push_back(right);
node merge;
merge.frequency=left->frequency+right->frequency;
merge.left_child=left;
merge.right_child=right;
queue.insert(merge);
}
}
}
//自顶向下编码
static void huffman_encoding(node*head){
//广度优先遍历
std::queue<node*>Q;
Q.push(head);
while (!Q.empty())
{
node*n=Q.front();
Q.pop();
if(n->left_child)
{
n->left_child->coding=n->coding;
n->left_child->coding.push_back(false);
Q.push(n->left_child);
}
if(n->right_child)
{
n->right_child->coding=n->coding;
n->right_child->coding.push_back(true);
Q.push(n->right_child);
}
}
}
static string huffman_decoding(node*head,vector<bool>coding)
{
if(coding.empty()||!(head->right_child)||!(head->left_child))
return head->words;
std::vector<bool>::iterator this_code=coding.begin();
if(*this_code)//右节点
{
coding.erase(this_code);
return huffman_decoding(head->right_child,coding);
}
else
{
coding.erase(this_code);
return huffman_decoding(head->left_child,coding);
}
}
static void main(){
//http://blog.csdn.net/xgf415/article/details/52628073
int frequency[5]={10,8,3,4,5};
string words[5]={"B","A","C","D","E"};
std::set<node>queue;
for(int i=0;i<5;i++)
{
node n;
n.frequency=frequency[i];
n.words=words[i];
queue.insert(n);
}
std::vector<node*>tree;
create_tree(queue,tree);
huffman_encoding(tree[tree.size()-1]);
//打印编码结果
for(std::vector<node*>::iterator it=tree.begin();it!=tree.end();it++)
{
if ((*it)->words=="")
continue;
std::cout<<(*it)->words<<":";
for (int i = 0; i <(*it)->coding.size() ; ++i) {
std::cout<<(*it)->coding[i];
}
std::cout<<std::endl;
}
//测试解码
string decode=huffman_decoding(tree[tree.size()-1],tree[0]->coding);
std::cout<<decode<<":";
for (int j = 0; j < tree[0]->coding.size(); ++j) {
std::cout<<tree[0]->coding[j];
}
std::cout<<std::endl;
}
};
#endif //DATA_STRUCT_TREE_H
(1)构建霍夫曼树:自底向上
根据统计频率构建霍夫曼树: A、把所有的节点扔进排序队列queue中; B、从queue选择选择前面两个最小的元素a、b,把最小的树a作为左节点,把最小的b作为右节点,以此构建父节点c(c的频率值为a+b的频率值),然后把a、b从队列删除、把c节点插入队列; C、循环(A)、(B)步骤构建霍夫曼树,直到queue为空。
(2)编码阶段:自顶向下
A、除了树的根节点没有码值之外,其他的根据左右子节点进行编码,做节点编码为0,右节点编码为1;
B、子节点在父节点码值的基础上,在后面加上一位对应的码值。
(3)解码阶段:自顶向下解码
根据给定的码值,从树根开始递归遍历,遇到0向左走,遇到1向又走,直到码值为空或者遇到叶子节点返回。
2、代码实现
#ifndef DATA_STRUCT_TREE_H
#define DATA_STRUCT_TREE_H
#include<vector>
#include <set>
#include <queue>
#include <string>
using namespace std;
class node{
public:
node(){
left_child=NULL;
right_child=NULL;
frequency=0;
coding.clear();
words="";
};
~node(){};
node* left_child;
node* right_child;
int frequency;
std::vector<bool> coding;
string words;
public:
bool operator <(const node& n1) const
{
return frequency<n1.frequency;
}
};
class huffman_coding{
public:
static void create_tree(std::set<node>&queue,std::vector<node*>&tree){
while (!queue.empty())
{
node *left= new node(*queue.begin());
queue.erase(queue.begin());
tree.push_back(left);
if (!queue.empty())
{
node *right=new node(*queue.begin());
queue.erase(*queue.begin());
tree.push_back(right);
node merge;
merge.frequency=left->frequency+right->frequency;
merge.left_child=left;
merge.right_child=right;
queue.insert(merge);
}
}
}
//自顶向下编码
static void huffman_encoding(node*head){
//广度优先遍历
std::queue<node*>Q;
Q.push(head);
while (!Q.empty())
{
node*n=Q.front();
Q.pop();
if(n->left_child)
{
n->left_child->coding=n->coding;
n->left_child->coding.push_back(false);
Q.push(n->left_child);
}
if(n->right_child)
{
n->right_child->coding=n->coding;
n->right_child->coding.push_back(true);
Q.push(n->right_child);
}
}
}
static string huffman_decoding(node*head,vector<bool>coding)
{
if(coding.empty()||!(head->right_child)||!(head->left_child))
return head->words;
std::vector<bool>::iterator this_code=coding.begin();
if(*this_code)//右节点
{
coding.erase(this_code);
return huffman_decoding(head->right_child,coding);
}
else
{
coding.erase(this_code);
return huffman_decoding(head->left_child,coding);
}
}
static void main(){
//http://blog.csdn.net/xgf415/article/details/52628073
int frequency[5]={10,8,3,4,5};
string words[5]={"B","A","C","D","E"};
std::set<node>queue;
for(int i=0;i<5;i++)
{
node n;
n.frequency=frequency[i];
n.words=words[i];
queue.insert(n);
}
std::vector<node*>tree;
create_tree(queue,tree);
huffman_encoding(tree[tree.size()-1]);
//打印编码结果
for(std::vector<node*>::iterator it=tree.begin();it!=tree.end();it++)
{
if ((*it)->words=="")
continue;
std::cout<<(*it)->words<<":";
for (int i = 0; i <(*it)->coding.size() ; ++i) {
std::cout<<(*it)->coding[i];
}
std::cout<<std::endl;
}
//测试解码
string decode=huffman_decoding(tree[tree.size()-1],tree[0]->coding);
std::cout<<decode<<":";
for (int j = 0; j < tree[0]->coding.size(); ++j) {
std::cout<<tree[0]->coding[j];
}
std::cout<<std::endl;
}
};
#endif //DATA_STRUCT_TREE_H
相关文章推荐
- [PY3]——内置数据结构(5)——字符串编码
- 哈夫曼树构建,编码,译码的实现------数据结构
- java主类结构、基本数据类型、 变量与常量、运算符、数据类型转换、代码注释与编码规范
- 赫夫曼树编码的表示与实现--自己写数据结构
- 看数据结构写代码(32) 赫夫曼树编码以及译码
- redis 3.2 新数据结构:quicklist、String的embstr与raw编码方式分界点
- 数据结构——霍夫曼树
- 数据结构中的赫夫曼树编码,KMP算法,图的深度优先遍历和广度优先遍历
- 数据结构课程设计——编码与译码
- 数据结构之哈弗曼树与哈弗曼编码
- 数据结构之哈弗曼编码的(Huffman Coding)加密解密压缩
- redis内存编码数据结构(整数集合、压缩列表)
- 数据结构实验4---用HuffmanTree进行编码、译码
- 数据结构——树(5):霍夫曼树
- 数据结构之霍夫曼树
- 数据结构——霍夫曼编码解码
- 数据结构之---C语言实现哈夫曼树和编码
- Huffman 编码 数据结构
- 数据结构实验2(设计哈弗曼编码和译码系统)
- 数据结构问题---哈夫曼树与编码问题