数据结构课程设计

来源:互联网 发布:qq美化主题软件 编辑:程序博客网 时间:2024/06/11 05:46

  题目要求:

设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。具体要求如下:

(1)将权值数据存放在数据文件(文件名为data.txt,位于执行程序的当前目录中)

(2)初始化:键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树;

(3)编码:利用建好的哈夫曼树生成哈夫曼编码;

(4)输出编码;

(5)设字符集及频度如下表:

字符空格 A B C D E F G H I J K L M
频度 186 64 13 22 32 103 21 15 47 57 1 5 32 20
字符 N O P Q R S T U V W X Y Z 
频度 57 63 15 1 48 51 80 23 8 18 1 16 1

 

 输入代码:

#include<iostream>#include<malloc.h>#include<stdio.h>#include <stdlib.h>#include<fstream>#include<cstring>#define N 50#define M 2*N-1using namespace std;typedef struct{    string data;//节点值    double weight;//权重    int parent;//双亲节点    int lchild;//左孩子节点    int rchild;//右孩子节点} HTNode;typedef struct{    char cd[N];//存放当前节点的哈夫曼编码    int start;//cd[start]~cd[n]存放哈夫曼编码} HCode;/*构造哈夫曼数*/void CreateHT(HTNode ht[],int n){    int i,k,lnode,rnode;    double min1,min2;    for(i=0; i<2*n-1; i++) //所有节点的相关域置为-1    {        ht[i].parent=ht[i].lchild=ht[i].rchild=-1;    }    for(i=n; i<2*n-1; i++)    {        min1=min2=32767;        lnode=rnode=-1;//lnode和rnode为权重最小的两个节点位置        for(k=0; k<=i-1; k++)            if(ht[k].parent==-1)//只在尚未构造二叉树的节点中查找            {                if(ht[k].weight<min1)                {                    min2=min1;                    rnode=lnode;                    min1=ht[k].weight;                    lnode=k;                }                else if(ht[k].weight<min2)                {                    min2=ht[k].weight;                    rnode=k;                }            }        ht[i].weight=ht[lnode].weight+ht[rnode].weight;        ht[i].lchild=lnode;        ht[i].rchild=rnode;//ht[i]作为双亲节点        ht[lnode].parent=i;        ht[rnode].parent=i;    }}/*由哈夫曼树生成哈夫曼编码*/void CreateHCode(HTNode ht[],HCode hcd[],int n){    int i,f,c;    HCode hc;    for(i=0; i<n; i++)//根据哈夫曼树求哈夫曼编码    {        hc.start=n;        c=i;        f=ht[i].parent;        while(f!=-1)//循环直到无双亲节点,即到达根节点为止        {            if(ht[f].lchild==c)//当前节点是双亲节点的左孩子节点                hc.cd[hc.start--]='0';            else//当前节点是双亲节点的右孩子节点                hc.cd[hc.start--]='1';            c=f;            f=ht[f].parent;//再对其双亲节点进行同样的操作        }        hc.start++;//start指向哈夫曼编码的开始字符        hcd[i]=hc;    }}/*输出对应的哈夫曼编码和平均长度*/void DispHCode(HTNode ht[],HCode hcd[],int n){    int i,k;    cout<<"输出对应的哈夫曼编码: "<<endl;    for(i=0; i<n; i++)    {        cout<<ht[i].data<<'\t';        for(k=hcd[i].start; k<=n; k++)        {            cout<<hcd[i].cd[k];        }        cout<<endl;    }}int main(){    int i,k,n;    string str[100];    double num[100];   // char SS='Y';    HTNode ht[M];    HCode hcd[N];   // while(SS!='N')    //{        cout<<"请输入字符集大小n : ";        cin>>n;        ifstream infile("data.txt",ios::in);        if(!infile)        {            cerr<<"open error!"<<endl;            exit(1);        }        else        {            cout<<"请输入n个字符: ";            for(i=0; i<n; i++)            {                cin>>str[i];                ht[i].data=str[i];            }            cout<<"请输入n个权值: ";            for(i=0; i<n; i++)            {                cin>>num[i];                ht[i].weight=num[i];            }            CreateHT(ht,n);            CreateHCode(ht,hcd,n);            DispHCode(ht,hcd,n);            for(i=0; i<n; i++)            {                for(k=hcd[i].start; k<=n; k++)                {                    infile>>hcd[i].cd[k];                }            }            ofstream outfile("data.txt",ios::out);            if(!outfile)            {                cerr<<"open error!"<<endl;                exit(1);            }            for(i=0; i<n; i++)            {                for(k=hcd[i].start; k<=n; k++)                {                    outfile<<hcd[i].cd[k];                }                outfile<<endl;            }            outfile.close();            cout<<endl;            //cout<<"请选择是否继续构造哈夫曼编码(Y/N):"<<endl;            //cin>>SS;        }  // }    return 0;}

运行截图:



权值数据保存在data.txt文件中:


总结:很走运抽到的课设题目不是很难,只是文件操作很久不用了,有点生硬。


0 0
原创粉丝点击