南航数据结构课设——Huffman编码与解码

Huffman编码与解码 (必做)(Huffman编码、二叉树)

[问题描述]

对一篇不少于5000字符的英文文章(source.txt),统计各字符出现的次数,实现Huffman编码(code.dat),以及对编码结果的解码(recode.txt)。

[基本要求]

(1) 输出每个字符出现的次数和编码,并存储文件(Huffman.txt)。

(2) 在Huffman编码后,英文文章编码结果保存到文件中(code.dat),编码结果必须是二进制形式,即0 1的信息用比特位表示,不能用字符’0’和’1’表示。

(3) 实现解码功能。

数据结构

用到的数据结构为二叉树、文本文件的读写、Huffman的编码与解码。

算法设计与思想

建立一个数组,从文件中一个个读取文章数据,利用哈希表的思想,根据所得字符的ASCII值在数组里分配地址,并对其值加一,以此统计字符的出现次数。

建立一个值为树结点的数组,存储文章的字符,每次选出ASCII值最小的两个字符作为新结点的左右子树,将新节点的权值置为左、右子树上根结点的权,即为ASCII值的和,再将刚刚所选的字符从数组里删除。重复上述步骤,直到构建出一个二叉树为止。设置数组存储编码,利用中序遍历依次递归遍历哈夫曼树,对哈夫曼树中存储的字符调用编码函数进行编码,编码函数也用递归实现,向左走为0,向右为1。对树中结点编码完毕后,从文章中依次读取字符,在树中查找相应的字符并存储编码到文件中;最后再从文件中读取哈弗曼编码,在树中查找字符,0便进入左子树,1便进入右子树,找到后直接输出

测试数据和结果

源代码

#include
#include 
#include
using namespace std; 
#define max 257
int zm[max]={0};          //存储每个字母的出现次数
int word[5000]={0};		  //存储字符
int num=0;				  //储存字符的总数量 
typedef struct BiTNode
{ 
	int weight;           //权值
	int word=300;             //字母(ASCLL码) 
	int code[150];        //Huffman编码 
	BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

void Statistic_zm(int zm[]) 
{
	ifstream readfile;
	readfile.open("source.txt");
	if(readfile.fail())
	{
		cout<<"不能打开文件"<weight < point[small]->weight )
                {
                    big = small ;
                    small  = j;
                }
                else if ( point[j]->weight < point[big]->weight )
                    big = j;
            }
        }
        //由最小权值树和次最小权值树建立一棵新树,q指向树根结点
        q = (BiTNode *) malloc ( sizeof(BiTNode) );
        q->weight = point[small]->weight + point[big]->weight;
        q->word = 300;
        q->lchild = point[small];
        q->rchild = point[big];
        point[small] = q;//将指向新树的指针赋给b指针数组中small位置
        point[big] = NULL;
    }
    
    T = q;	
}
void bianma_T ( BiTree T, int b[], int ch, int n )
{
    int i;
    if ( T )
    {
        if ( ch == T->word )//复制编码
        {
            b[0] = n;//存储编码长度
            for( i=0; i<=n; i++ )
            {
                T->code[i] = b[i];
            }
        }
        else
        {
            b[n]=0;
            bianma_T ( T->lchild , b ,  ch , n+1 );
            b[n]=1;
            bianma_T ( T->rchild , b , ch , n+1  );
        }
    }
}
//利用递归依次创建编码
void Creat_HCode ( BiTree T ,  BiTree B )
{
    if ( T == NULL )
    {
        return;
    }
    else
    {
      if ( T->word!=300 )//若此节点为文章内的字符,则对它进行编码
      {
          int ch = T->word;
          int b[100];
          bianma_T ( B , b , ch , 1);
      }
      Creat_HCode ( T->lchild , B );
      Creat_HCode ( T->rchild , B);
    }
}
void WriteCode ( BiTree T )
{
   int i;
   if ( T == NULL )
   {
       return;
   }
   else
   {
       WriteCode( T->lchild );
       if ( T->word!=300 )//若此节点为文章内的字符,则向Huffman.txt存储结点信息
       {
          ofstream read_out;
          read_out.open( "Huffman.txt", ios::app );
          if( !read_out )
          {
            cout<< "文件打开失败!" <word;//将整型转化为字符型
          read_out<< "字符:"<< ch <<" 出现次数:"<< T->weight <<" 编码:";
          for( i=1; i < T->code[0]; i++ )
          read_out<< T->code[i];
          read_out<rchild);
    }
}

BiTNode* search(BiTree T,int ch)
{
	BiTNode* p=NULL;
	if(T==NULL) return NULL;
	else if(T->word==ch) return T;
	else
	{
		p=search(T->lchild,ch);
		if(p==NULL) return search(T->rchild,ch);
		else return p;
	}
}
void StorageCode(BiTree T)
{   char ch;
	BiTNode* p;
    ifstream readfile;
	readfile.open("source.txt");
	fstream file("code.dat",ios::out | ios::binary);
	if(readfile.fail())
	{
		cout<<"不能打开文件"<code[0];
		for(int i=1;icode[0];i++)
	     H[i]=p->code[i];
	    file.write((char*)H, sizeof(H));
	}
	readfile.close();
	file.close();
}
int jiema ( BiTree T, int H[] )
{
    int i=0;
    for( i=1; ilchild;
        else if ( H[i]==1 )
        T = T->rchild;
    }
    return T->word;
}
void CrackCode(BiTree T)
{
	int y, H[20];
	char ch;
	fstream file("code.dat",ios::in | ios::binary);
	
	fstream writefile;
	writefile.open("recode.txt");
	if(writefile.fail())
	{
		cout<<"不能打开文件"<>ch;
	int y=(int)ch;
	BiTNode* p=search(T,y);
	for(int i=1;icode[0];i++)
	printf("%d",p->code[i]);*/
	StorageCode(T);
	CrackCode(T);
}

Source.txt文件中的内容

南航数据结构课设——Huffman编码与解码_第1张图片

Huffman.txt文件中的内容

南航数据结构课设——Huffman编码与解码_第2张图片 recode.txt文件中的内容

南航数据结构课设——Huffman编码与解码_第3张图片

你可能感兴趣的:(数据结构,算法,霍夫曼树,链表)