好文档 - 专业文书写作范文服务资料分享网站

实习报告6_哈夫曼编码

天下 分享 时间: 加入收藏 我要投稿 点赞

.. ..

1.初始化:从文件humanWeight.txt( 程序运行时,由用户输入 )读入字符集大小n,以

及n个字符和n个权值,建立哈夫曼树,将它存于文件hufTree.txt中。

2.编码:利用已建好的哈夫曼树(如不在存,则从文件hufTree.txt中读入)对 文件

tobebin.txt字符集中的每一个进行编码,将结果放在codefile.txt 中。

3.译码:利用已建好的哈夫曼树将 codefile.txt 中的代码进行译码,结果保存在

textfile.txt 中。

4.印代码文件。将文件 codefile.txt 以紧凑的格式显示在终端上,每行50个

代码。同时将结果保存在 codeprint.txt 中。

二.概要设计:

1.哈夫曼树的抽象数据类型定义:

ADT haffman

{ 数据对象:D={ai|ai为charnode型的结点,i=1,2,3,……n,n>0} 数据关系:R={|ai是D上的元素}

} ADT haffman

2.编码集结构体的抽象数据类型的定义:

ADT code

{ 数据对象:D1={ai| ai是charlink型的结点,i=1,2,……n,n>0}

D2={bi|bi是codelink型的结点,i=1,2,……n,n>0} 数据关系: R1={|ai是D1上的元素}

R2={|bi是D2上的元素}

} ADT code

3.程序分为四个部分:

1)读入字符集以及相应频度,建立哈夫曼树。 2)根据哈夫曼树得到每一个字符的哈夫曼编码。

3)读入要编码的字符串,根据哈夫曼树和编码集求出字符串的哈夫曼编码。 4)根据哈夫曼编码和哈夫曼树得到字符串。

三.详细设计:

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////zy //

// 赫夫曼编/译码器 // 朱勇 13011090 //

////////////////////////////////////////////////////////////////////////////////

///////////////////

#include #include #include #include

using namespace std;

... . .

.. ..

/////////////////////////////////////////////////////////// // 赫夫曼树和赫夫曼编码的存储表示 typedef struct { unsigned int weight; unsigned int parent , lChild , rChild;

} HTNode , *HuffmanTree; // 动态分配数组存储赫夫曼树

typedef struct { char ch; char* hufCh;

} HuffmanCode; // 动态分配数组存储赫夫曼编码表

/////////////////////////////////////////////////////////// // 权值字符结点类型 typedef struct { char ch; int wt;

} wElem; // 动态分配数组存储读入字符与权值

/////////////////////////////////////////////////////////// // 赫夫曼编码函数

void HuffmanCoding( HuffmanTree & , HuffmanCode * , wElem * , int );

/////////////////////////////////////////////////////////// // 对文件 tobebin.txt 中的正文进行编码 // 将结果存入 codefile.txt

void EnCoding( HuffmanCode * , const char* );

/////////////////////////////////////////////////////////// // 对文件 codefile.txt 里的代码进行译码 // 将结果存入 textfile.txt

void DeCoding( HuffmanTree , HuffmanCode * , const char* , const int );

/////////////////////////////////////////////////////////// // 对 codefile.txt 里的代码进行编排,显示,打印 void PrintCode( const char* , const char* );

/////////////////////////////////////////////////////////// // 选择两个最小的结点

void SelectTwoNode( HuffmanTree , int , int& , int& );

int main() { //

... . .

.. ..

// 用文件流对象 hufInPut 打开外部文件

// humanWeight.txt 储存字符集大小 n ,以及 n 个字符和 n 个权值 ifstream hufInPut( \int hufNum = 0;

hufInPut >> hufNum; // 读入字符集大小 n 到 hufNum

wElem* hufW = new wElem[ hufNum ]; // 分配 n 个字符和 n 个权值的储存空间 for( int ii = 0 ; ii < hufNum ; ii++ ) {

//

// 循环读入字符及其对应的权值

hufInPut >> hufW[ ii ].ch >> hufW[ ii ].wt; }

hufInPut.close(); // 关闭 humanWeight.txt 文件

HuffmanTree hufT; // 空树

HuffmanCode* hufC = ( HuffmanCode* ) malloc ( ( hufNum + 1 ) * sizeof( HuffmanCode ) ); // 分配n个字符编码的头指针向量 HuffmanCoding( hufT , hufC , hufW , hufNum ); // 编码中...

//

// 用文件流对象 hufTreeOutPut 把赫夫曼树 HT , HC 输出到文件 hufTree.txt 中 ofstream hufTreeOutPut( \

hufTreeOutPut << \setw( 9 )

<< \<< endl;

for( int tOut = 1 ; tOut <= 2*hufNum-1 ; tOut++ ) {

hufTreeOutPut << setw( 6 ) << tOut << setw( 8 ) << hufT[ tOut ].weight << setw( 8 ) << hufT[ tOut ].parent << setw( 8 ) << hufT[ tOut ].lChild << setw( 8 ) << hufT[ tOut ].rChild << endl; }

hufTreeOutPut << \ << \for( int cOut = 1 ; cOut <= hufNum ; cOut++ ) {

hufTreeOutPut << \hufC[ cOut ].hufCh << endl; }

hufTreeOutPut << \hufTreeOutPut.close(); // 输出完毕,关闭文件 delete [] hufW; // 释放存

EnCoding( hufC , \// 对正文编码

... . .

.. ..

DeCoding( hufT , hufC , \// 译码 PrintCode( \// 打印代码 cout << endl; return 0; }

////////////////////////////////////////////////////////////////////////////////

////////////////// //

// w 存放 n 个字符的权值( 均大与0 )

// 构造赫夫曼树 HT , 并求出 n 个字符的赫夫曼编码 HC //

void HuffmanCoding( HuffmanTree &HT , HuffmanCode* HC , wElem* w , int n ) { if( n <= 1 ) return; int m = 2 * n - 1; // 赫夫曼树的结点数目 HT = ( HuffmanTree ) malloc ( ( m + 1 ) * sizeof( HTNode ) ); //0 号单元未用 HuffmanTree p = HT; p++; // p 指向 HT 的第 1 号单元 int i=0 , ww=0; // ww 为 wElem* w 的下标 for( i = 1 ; i <= n ; i++ , p++ , ww++ ) { p->weight = w[ww].wt; p->parent = p->lChild = p->rChild = 0; // } // 初始化 for( ; i <= m ; ++i , ++p ) // { p->weight = p->parent = p->lChild = p->rChild = 0; } // // 建赫夫曼树 // 在 HT[ 1 .. i-1 ]选择parent 为 0 且 weight 最小的两个结点,其序号分别为

s1 和 s2 // int s1=0 , s2=0; for( i = n + 1 ; i <= m ; ++i ) { SelectTwoNode( HT , i-1 , s1 , s2 ); HT[ s1 ].parent = i; // 标记 parent HT[ s2 ].parent = i; // 标记 parent HT[ i ].lChild = s1; // 标记左孩子 HT[ i ].rChild = s2; // 标记右孩子 HT[ i ].weight = HT[ s1 ].weight + HT[ s2 ].weight; // 新结点的权值 } // // 从叶子到根逆向求每个字符的赫夫曼编码

... . .

.. ..

} // end HuffmanCoding()

////////////////////////////////////////////////////////////////////////////////

////////////////// //

// 选择两个最小的结点 , 序号分别放在 s1 和 s2 中 //

void SelectTwoNode( HuffmanTree HT , int i , int& s1 , int& s2 ) { unsigned int sm1 , sm2; // 用于权值的比较 s1 = 1; // 从序号为 1 的权值开始 s2 = 1; int m=0; // 最小权值的序号临时变量 for( m = 1 ; m <= i ; m++ ) // 第一遍中第一个 parent 为 0 的结点 { if( HT[ m ].parent != 0 ) continue; else { sm1 = HT[ m ].weight; s1=m; break; } } for( int j = m+1 ; j <= i ; j++ ) // 第一遍选第一个最小的 { if( HT[ j ].parent != 0 ) continue; else {

... . .

//

char* cd = new char[ n ]; // 分配求编码的工作空间 cd[ n - 1 ] = '\\0'; // 编码结束符 int c = 0; int f = 0;

for( i = 1 ; i <= n ; ++i ) // 逐个字符求赫夫曼编码 {

int start = n - 1; // 编码结束符位置

for( c = i , f = HT[ i ].parent ; f != 0 ; c = f , f = HT[ f ].parent ) // 从叶子到根逆向求编码 { if( HT[ f ].lChild == c ) { cd[ --start ] = '0'; } else { cd[ --start ] = '1'; } }

HC[ i ].ch = w[ i-1 ].ch ; // 复制字符

HC[ i ].hufCh = ( char* ) malloc ( ( n - start ) * sizeof( char ) ); // 为第 i 个字符编码分配空间

strcpy( HC[ i ].hufCh , &cd[ start ] ); // 从 cd 复制编码到 HC }

delete [] cd; // 释放工作空间

实习报告6_哈夫曼编码

....1.初始化:从文件humanWeight.txt(程序运行时,由用户输入)读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,将它存于文件hufTree.txt中。2.编码:利用已建好的哈夫曼树(如不在存,则从文件
推荐度:
点击下载文档文档为doc格式
41ro24bq0w8az813jgo32teb88j4b1005si
领取福利

微信扫码领取福利

微信扫码分享