哈夫曼编码
哈夫曼编码定义:
它是由n个带权叶子结点构成的所有二叉树中带权路径长度最短的二叉树。因为这种树最早由哈夫曼(Huffman)研究,所以称为哈夫曼树,又叫最优二叉树。
哈夫曼编码原理:百度百科
哈夫曼树是一种树形结构,用哈夫曼树的方法解编程题的算法就叫做哈夫曼算法。树并不是指植物,而是一种数据结构,因为其存放方式颇有点象一棵树有树叉因而称为树。 最简哈夫曼树是由德国数学家冯.哈夫曼 发现的,此树的特点就是引出的路程最短。概念理解:(1)路径 从树中一个节点到另一个节点之间的分支构成这两个节点之间的路径。(2)路径长度 路径上的分支数目称作路径长度。编码原理详解相关博文:相关博文
实现步骤:
(1)初始化: 根据给定的n个权值{w1,w2,…wn}构成n棵二叉树的集合F={T1,T2,..,Tn},其中每棵二叉树Ti中只有一个带权wi的根结点,左右子树均空。
(2)找最小树:在F中选择两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,且至新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
(3)删除与加入:在F中删除这两棵树,并将新的二叉树加入F中。
(4) 判断:重复前两步(2和3),直到F中只含有一棵树为止。该树即为哈夫曼树
C++实现源码:
#include<iostream>
#include<iomanip>
#include <functional>
#include<queue>
using namespace std;
#define SIZE 8
typedef unsigned int WeightType;
#define NIL -1
struct HaffNode//哈夫曼树节点
{
WeightType weight;//权值
int parent;
int leftchild;
int rightchild;
};
typedef HaffNode HaffManTree[SIZE*2];
struct HaffCode
{
char ch;
char code[SIZE+1];
};
typedef HaffCode HaffCoding[SIZE+1];
//初始化哈夫曼树
void Init_HaffTree(HaffManTree hft)
{
for(int i = 0;i<SIZE*2;++i)
{
hft[i].weight = NIL;
hft[i].parent = 0;
hft[i].leftchild = 0;
hft[i].rightchild = 0;
}
for(int i =1;i<=SIZE;++i)
{
cin>>hft[i].weight;
}
}
bool Get2Min(HaffManTree hft,int n,int& index1,int& index2)
{
int i = 1;
while(i<n && hft[i].parent != 0) ++i;
if(i == n) return false;
for(int j = i+1;j<n;++j)
{
if(hft[j].parent == 0 && hft[i].weight > hft[j].weight)
{
i = j;
}
}
index1 = i;
hft[i].parent = -1;
i = 1;
while(i<n && hft[i].parent != 0) ++i;
if(i == n) return false;
for(int j = i+1;j<n;++j)
{
if(hft[j].parent == 0 && hft[i].weight > hft[j].weight)
{
i = j;
}
}
index2 = i;
hft[i].parent = -1;
return true;
}
void Create_HaffTree(HaffManTree hft)
{
struct IndexNode
{
int index;
WeightType w;
operator WeightType() const { return w;}
};
priority_queue<IndexNode,vector<IndexNode>,greater<IndexNode> > q2min;
for(int i = 1;i<=SIZE;++i)
{
IndexNode x ={ i,hft[i].weight};
q2min.push(x);
}
int k = SIZE+1;
while(k < SIZE*2)
{
if(q2min.empty()) break;
IndexNode m1 = q2min.top(); q2min.pop();
if(q2min.empty()) break;
IndexNode m2 = q2min.top(); q2min.pop();
hft[k].weight = hft[m1.index].weight + hft[m2.index].weight;
hft[k].leftchild = m1.index;
hft[k].rightchild = m2.index;
hft[m1.index].parent = k;
hft[m2.index].parent = k;
IndexNode x={k,hft[k].weight};
q2min.push(x);
++k;
}
}
//打印哈夫曼树
void Print_HaffTree(HaffManTree hft)
{
for(int i = 1;i<SIZE*2; ++i)
{
cout<<setw(3)<<i;
cout<<setw(4)<<hft[i].weight;
cout<<setw(4)<<hft[i].parent;
cout<<setw(4)<<hft[i].leftchild;
cout<<setw(4)<<hft[i].rightchild<<endl;
}
cout<<endl;
}
void Init_HaffCode(HaffCoding hc)
{
for(int i=0;i<SIZE+1;++i)
{
hc[i].ch = '\0';
memset(hc[i].code,0,sizeof(char)*(SIZE+1));
}
for(int i = 1;i<SIZE+1;++i)
{
cin>>hc[i].ch;
}
}
void Print_HaffCode(HaffCoding hc)
{
for(int i = 1;i<SIZE+1;++i)
{
cout<<hc[i].ch<<"-> "<<hc[i].code<<endl;
}
cout<<endl;
}
void Create_HaffCode(HaffManTree hft,HaffCoding hc)
{
char code[SIZE+1];
for(int i = 1;i<=SIZE;++i)
{
int c = i;
int pa = hft[c].parent;
int k = SIZE;
code[k] = '\0';
while(pa != 0)
{
code[--k] = hft[pa].leftchild == c? '1':'0';
c = pa;
pa = hft[c].parent;
}
strcpy(hc[i].code,&code[k]);
}
}
void main()
{
HaffManTree hft;
HaffCoding hc;
Init_HaffTree(hft);
Init_HaffCode(hc);
Create_HaffTree(hft);
Print_HaffTree(hft);
Create_HaffCode(hft,hc);
Print_HaffCode(hc);
}

本文介绍了哈夫曼编码的定义,详细讲解了哈夫曼编码的原理,并提供了C++实现哈夫曼编码的步骤及源码。

6228

被折叠的 条评论
为什么被折叠?



