huffman编码

/********************************************
--程序描述:	数据结构huffman编码的实现
--修改日期:	2009.5.31
--修改人:		吴强
--修改原因:	从前写的程序不够规范
--输入要求:	输入要编码的.txt文件名
********************************************/
#include 
#include 
#include 

const int N=26;
const int M=2*N-1;
const int Max=10000;

typedef struct 
{
    char c;
    int w;
    int lint;
    int rint;
}NODE;

NODE htree[M];

//把文件的操作定义成一个类
class Cfile
{
    private:
        char *fname;
    	FILE *fp;

    public:
    	void Openfile();
    	void sort();
    	void Closefile()
    	{
	    fclose(fp);
	    delete[] fname;
    	}
};

//打开指定文件,并记录各字母(大小写异同)出现次数
void Cfile::Openfile()
{
    fname=new char[50];

    cin>> fname;

    if ( ( fp=fopen(fname,"r") )==NULL )
    {
    	cout<<"openfile error";
    	exit(0);
    }

    while ( !feof(fp) )
    {
    	int k;
    	char ch=fgetc(fp);

	//如果不是大小写字母就跳过
    	if ( (ch< 'a' || ch> 'z') && (ch< 'A' || ch> 'Z') )   
    	{
    	    continue;
    	}

    	if (ch>= 'A' && ch<= 'Z')
    	{
    	    ch+=32;          //小写换成大写
    	}

    	int i=0;
    	int j=N-1;

    	while ( i<= j )			//二分查找,记录各字母权值
    	{
    	    k=(i+j)/2;

    	    if (ch < htree[k].c)
    	    {
    	        j=k-1;
            }
    	    else if (ch > htree[k].c)
    	    {
    	        i=k+1;
    	    }
    	    else  
    	    {    
    	    	htree[k].w+=1;
    	    	break;  
    	    }

    	}
    }
}

void Cfile::sort()
{
    NODE jh;

    //冒泡法按权值大小排序
    for ( int i=0; i< N; i++ )   
    {
    	int k=0;

    	for ( int j=0; j< N-i+1; j++ )
    	{
    	    if ( htree[j].w> htree[j+1].w )
            {
    	    	jh=htree[j];
    	    	htree[j]=htree[j+1];
    	    	htree[j+1]=jh;

    	    	k=1;
            }
    	}

    	if (!k)
    	{
	    break;
    	}
    }	
}

//定义栈
class st
{
    private:
        int stack[N];
        int top;

    public:
        st();
        void Push(int);
        void Pop();
        void PutStack(); 
};

st::st()
{
    for ( int i=0; i< N; i++ )
    {
        stack[i]=Max;
    }

    top=-1;
}
	    
void st::Push(int x)
{
    stack[++top]=x;
}

void st::Pop()
{
    stack[top]=Max;
    top--;
}

void st::PutStack()
{
    for ( int i=0; i<= top; i++ )
    {
        cout<< stack[i];
    }

    cout<< endl;
}


class huffman
{
    private:
        int l;

    public:
        huffman() 
        { 
			l=0; 
    	}
    	void Create_ht();
    	void TraverseTree(int);

    public:
    	st code;
};

void huffman::Create_ht()
{
    int i=0;
    int j=N;
    int k=N;

    int min_1;
    int min_2;

    while ( j< M )
    {
    	if ( i< N && htree[i].w<= htree[j].w )
    	{
    	    min_1=i++;

    	    if ( i< N && htree[i].w<= htree[j].w )
	    {
		min_2=i++;
	    }
	    else 
	    {
		min_2=j++;
	    }
    	}
    	else 
    	{
    	    min_1=j++;

    	    if ( i< N && htree[i].w<= htree[j].w )
	    {
    	        min_2=i++;
    	    }
    	    else 
            {
    	        min_2=j++;
	    }
    	}

    	htree[k].w=htree[min_1].w+htree[min_2].w;
    	htree[k].lint=min_1;
    	htree[k].rint=min_2;

    	k++;
    }
} 

void huffman::TraverseTree(int root)
{
    if ( htree[root].rint!=-1 )
    {
    	code.Push(0);
    	TraverseTree(htree[root].rint);
    	code.Pop();

    	code.Push(1);
    	TraverseTree(htree[root].lint);
    	code.Pop();
    }
    else 
    {
    	cout<< l++;
    	cout<< "   "<< htree[root].c<< "  ";

    	code.PutStack();
        cout<< endl;
    }
}	   
	 

void main()
{
    inline void Init_ht();
    Init_ht();

    Cfile ff;       

    ff.Openfile();
    ff.sort();
    ff.Closefile();

    huffman ht;      
    ht.Create_ht();

    cout<< "huffman编码:"<< endl;
    ht.TraverseTree(M-1);

    cout<< "统计: "<< endl;

    for ( int i=0; i< N; i++)
    {
    	cout<< "   "<< htree[i].c<< "   "<< htree[i].w<< "个"<< endl;
    }
}

void Init_ht()
{
    for ( int i=0; i< N; i++ )
    {
    	htree[i].c='a'+i;
    	htree[i].w=0;
    	htree[i].lint=-1;
    	htree[i].rint=-1;
    }
    for ( i=N; i< M; i++)
    {
    	htree[i].c='#';
    	htree[i].w=Max;
    	htree[i].lint=-1;
    	htree[i].rint=-1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值