易网时代-编程资源站
Welcome
微信登录
编程资源
图片资源库
蚂蚁家优选
PDF转换器
软件资源
软件开发
、
小程序制作
、
系统集成与运维
、
空间租用
、
硬件开发
、
视频监控
、
技术咨询与支持
——联系电话:0311-88999002/88999003
首页
/
操作系统
/
Linux
/
C++实现:霍夫曼编码
C++实现:霍夫曼编码:
#ifndef CHUFFMANTREE_H_
#define CHUFFMANTREE_H_
#include <assert.h>
#include <iostream>
#include <string>
#include <deque>
using
namespace
std;
/***************************************************************************/
/*先谈谈霍夫曼编码的基本思想:
/*对于一个给定的概率数组,所有元素之和为1,为了便于算法实现,我们扩大100倍
/*选出序列中最小的两个元素,删除原序列中的这两个数,相加得到一个新的元素
/*再把新得到的数放入序列中,重复上述过程,直到序列中只有一个元素(100)
/*规定:1、左孩子必须不大于右孩子节点的值;2、左边编码为0,右边为1
/***************************************************************************/
typedef
struct
_ITEM
{
int
index;
//元素在原来的数组中的索引值
int
data;
//数据
}ITEM,*PITEM;
typedef
struct
_TREE
{
_TREE* lChild;
//指向左孩子
_TREE* rChild;
//指向右孩子
_TREE* pParent;
//指向父节点
ITEM item;
//当前节点的数据域
}TREE,*PTREE;
class
CHuffmanTree
{
public
:
CHuffmanTree(
int
s[],
const
int
len);
virtual
~ CHuffmanTree();
//初始化树
void
InitTree()
const
;
//打印输入的数据
void
ShowBuffer()
const
;
//打印树
void
ShowTree()
const
;
void
ShowHuffmanCode();
protected
:
//对队列元素进行两次冒泡排序,以便选出最小的两个数
void
SortDeque();
//选出队列中最小的两个元素构造新的树节点
void
Select(
int
& m,
int
& n);
//构造哈弗曼树
void
CreateHuffmanTree();
private
:
int
* pBuffer;
//把元素复制到自己的内存里,指向首地址
int
m_iLength;
//数组元素个数
PTREE pTree;
deque<ITEM> que;
//双向队列,在这里面进行筛选最小的两个
};
#endif;
#ifndef CHUFFMANTREE_H_#define CHUFFMANTREE_H_#include <assert.h>#include <iostream>#include <string>#include <deque>using namespace std;/***************************************************************************//*先谈谈霍夫曼编码的基本思想:/*对于一个给定的概率数组,所有元素之和为1,为了便于算法实现,我们扩大100倍/*选出序列中最小的两个元素,删除原序列中的这两个数,相加得到一个新的元素/*再把新得到的数放入序列中,重复上述过程,直到序列中只有一个元素(100)/*规定:1、左孩子必须不大于右孩子节点的值;2、左边编码为0,右边为1/***************************************************************************/typedef struct _ITEM{int index;//元素在原来的数组中的索引值int data;//数据}ITEM,*PITEM;typedef struct _TREE{_TREE* lChild;//指向左孩子_TREE* rChild;//指向右孩子_TREE* pParent;//指向父节点ITEM item;//当前节点的数据域}TREE,*PTREE;class CHuffmanTree{public:CHuffmanTree(int s[],const int len);virtual~ CHuffmanTree();//初始化树void InitTree()const;//打印输入的数据void ShowBuffer()const;//打印树void ShowTree()const;void ShowHuffmanCode();protected://对队列元素进行两次冒泡排序,以便选出最小的两个数void SortDeque();//选出队列中最小的两个元素构造新的树节点void Select(int& m,int& n);//构造哈弗曼树void CreateHuffmanTree();private:int* pBuffer;//把元素复制到自己的内存里,指向首地址int m_iLength;//数组元素个数PTREE pTree;deque<ITEM> que;//双向队列,在这里面进行筛选最小的两个};#endif;
[cpp]
view plaincopyprint?
#include "stdafx.h"
#include "HuffmanTree.h"
CHuffmanTree::CHuffmanTree(
int
s[],
const
int
len)
:pBuffer(NULL)
,pTree(NULL)
,m_iLength(0)
{
assert(len>0);
pBuffer=
new
int
[len];
int
* p=pBuffer;
for
(
int
i=0;i<len;++i)
{
ITEM it;
it.index=i;
it.data=s[i];
que.push_back(it);
*(p+i)=s[i];
}
m_iLength=len;
pTree=
new
TREE[2*len-1];
InitTree();
}
CHuffmanTree::~CHuffmanTree()
{
//回收内存
if
(pTree)
{
delete
[] pTree;
pTree=NULL;
}
if
(pBuffer)
{
delete
[] pBuffer;
pBuffer=NULL;
}
}
void
CHuffmanTree::InitTree()
const
{
int
* p=pBuffer;
int
i=0;
for
(;i<2*m_iLength-1;++i)
{
(pTree+i)->lChild=NULL;
(pTree+i)->rChild=NULL;
(pTree+i)->pParent=NULL;
(pTree+i)->item.index=i;
}
for
(i=0;i<m_iLength;++i)
(pTree+i)->item.data=*(p+i);
for
(;i<2*m_iLength-1;++i)
(pTree+i)->item.data=0;
}
void
CHuffmanTree::ShowBuffer()
const
{
for
(
int
i=0;i<m_iLength;++i)
cout<<*(pBuffer+i)<<
" "
;
cout<<endl;
}
void
CHuffmanTree::ShowTree()
const
{
cout<<
"index lChild rChild pParent data"
<<endl;
for
(
int
i=0;i<2*m_iLength-1;++i)
{
cout<<(pTree+i)->item.index<<
" "
;
if
((pTree+i)->lChild)
cout<<(pTree+i)->lChild->item.data<<
" "
;
else
cout<<
"0 "
;
if
((pTree+i)->rChild)
cout<<(pTree+i)->rChild->item.data<<
" "
;
else
cout<<
"0 "
;
if
((pTree+i)->pParent)
cout<<(pTree+i)->pParent->item.data<<
" "
;
else
cout<<
"0 "
;
cout<<(pTree+i)->item.data<<endl;
}
}
void
CHuffmanTree::Select(
int
& m,
int
& n)
{
if
(que.size()<2)
return
;
SortDeque();
//经过两次冒泡排序,最小的两个元素的索引当然是0和1了
m=que.at(0).index;
n=que.at(1).index;
//出队列
que.pop_front();
que.pop_front();
}
void
CHuffmanTree::SortDeque()
{
if
(que.empty())
return
;
//两次冒泡排序就可以筛选出最小的两个了
for
(
int
i=0;i<2;++i)
{
for
(
int
j=que.size()-1;j>i;--j)
{
if
(que.at(j).data<que.at(j-1).data)
{
ITEM temp=que.at(j);
que.at(j)=que.at(j-1);
que.at(j-1)=temp;
}
}
}
}
void
CHuffmanTree::CreateHuffmanTree()
{
for
(
int
i=m_iLength;i<2*m_iLength-1;++i)
{
int
m=0,n=0;
Select(m,n);
(pTree+m)->pParent=(pTree+i);
(pTree+n)->pParent=(pTree+i);
(pTree+i)->lChild=(pTree+m);
(pTree+i)->rChild=(pTree+n);
(pTree+i)->item.index=i;
(pTree+i)->item.data=(pTree+m)->item.data+(pTree+n)->item.data;
que.push_back((pTree+i)->item);
//关键!产生的新节点一定要放入队列中
}
}
void
CHuffmanTree::ShowHuffmanCode()
{
CreateHuffmanTree();
//生成霍夫曼树
for
(
int
i=0;i<m_iLength;++i)
{
TREE* p=(pTree+i);
string s=
""
;
while
(p->pParent)
{
//我们约定左0,右1
if
(p->pParent->lChild->item.index==p->item.index)
s+=
"0"
;
else
s+=
"1"
;
p=p->pParent;
}
s=string(s.rbegin(),s.rend());
//逆置
cout<<(pTree+i)->item.data<<
"的编码为:"
<<s<<endl;
//打印每个元素的霍夫曼编码
}
}
代码有注释,在此不再啰嗦.测试:
#include "stdafx.h"
#include <iostream>
#include "huffmantree.h"
using
std::cout;
using
std::endl;
int
_tmain(
int
argc, _TCHAR* argv[])
{
int
s[]={5,29,7,8,14,23,3,11};
CHuffmanTree tree(s,8);
tree.ShowBuffer();
tree.ShowTree();
tree.ShowHuffmanCode();
tree.ShowTree();
return
0;
}
收藏该网址
版权所有©石家庄振强科技有限公司2024
冀ICP备08103738号-5
网站地图