zoukankan      html  css  js  c++  java
  • 2019.6.24-2019.6.28(实训数据结构)4.树和二叉树应用项目

    2019.6.24-2019.6.28(实训数据结构) 书籍:《数据结构项目实训教程》 赵君喆,戴文华

    6.3树和二叉树应用项目

    输入一串字符,建立哈夫曼树,然后编码解码

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<cstring>
    #include<fstream>
    #include<iomanip>
    #include<algorithm>
    using namespace std;
    
    char A[50]={};
    
    //构建哈夫曼树结点,包含权重,父节点,左孩子和右孩子 
    typedef struct{
        int weight;
        int parent,lchild,rchild;
    }HTNode,*HuffmanTree;
    
    typedef char **HuffmanCode;
    
    //计算不同字符的个数
    void Calculate_weight(char a[],char b[],int m,int n,int *w){
        int i,j;
        for(i=0;i<n;i++){
            for(j=0;j<m;j++){
                if(b[i]==a[j]){
                    A[i+1]=w[i+1]++;
                }
            }
        }
    } 
    
    //找到最小的两个结点 
    void FindNode(HuffmanTree HT,int n,int &t1,int &t2){
        //构建哈夫曼二叉树 
        HT[0].weight=100;
        t1=0;
        t2=0;
        for(int i=1;i<=n;i++){
            if(HT[i].parent==0){
                if(HT[i].weight<HT[t2].weight){
                    if(HT[t2].weight<HT[t1].weight){
                        t1=t2;
                    }
                    t2=i;
                }
                else if(HT[i].weight<HT[t1].weight){
                    t1=t2;
                    t2=i;
                }
            }
        } 
    } 
    
    //将Huffman二叉树的结构写入output_tree_info.txt
    void output_tree_info(HuffmanTree HT,int m){
        //将Huffman二叉树的结构表存入文件 output_tree_info.txt
        int i;
        //写入output_tree_info.txt
        ofstream outfile("output_tree_info.txt");
        outfile<<"编号 权重 父结点 左孩子 右孩子"<<endl;
        for(i=1;i<=m;i++){
            outfile<<i<<"	";
            outfile<<HT[i].weight<<"	";
            outfile<<HT[i].parent<<"	";
            outfile<<HT[i].lchild<<"	";
            outfile<<HT[i].rchild<<endl;
        } 
    }
    
    //将Huffman编码表写入output_code_info.txt 
    void output_code_info(char b[],HuffmanCode HC,int n){
        //将Huffman编码表写入output_code_info.txt
        int i;
        //写入output_code_info.txt
        ofstream outfile("output_code_info.txt");
        outfile<<"编码表:"<<"	"<<"编码频度"<<endl;
        for(i=1;i<=n;i++){
            outfile<<b[i-1]<<":"<<HC[i]<<"	"<<A[i]+1<<endl;
        } 
    }
    
    //为哈夫曼二叉树进行编码,构造Huffman二叉树HT,并求出n个字符的哈夫曼二叉树 
    void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){
        //用w存放n个字符的权值,构造哈夫曼树HT
        //并求出n个字符的哈夫曼编码HC
        int m,i,t1,t2,start;
        unsigned c,f;
        HuffmanTree p;
        char *cd;
        m=2*n-1;
    
        HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
        for(p=HT+1,i=1;i<=n;i++){//前n个结点初始化 
            p->weight=w[i];
            p->parent=0;
            p->lchild=0;
            p->rchild=0; 
        } 
        for(;i<=m;i++,p++){//第n+1个顶点到2n-1个顶点初始化 
            p->weight=0;
            p->parent=0;
            p->lchild=0;
            p->rchild=0;
        }
            
        for(i=n+1;i<=m;i++){//构建哈夫曼树 
            FindNode(HT,i-1,t1,t2);
            HT[t1].parent=i;
            HT[t2].parent=i;
            HT[i].lchild=t1;
            HT[i].rchild=t2;
            HT[i].weight=HT[t1].weight+HT[t2].weight;
        }
        output_tree_info(HT,m);//将树结构写入文件
        //求每个字符的哈夫曼编码(从叶子结点到根结点逆向进行)
        HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
        cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间
        cd[n-1]='';//编码结束符
        for(i=1;i<=n;i++){//逐个字符求哈夫曼编码 
            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';
                }
            } 
            //为第i个字符分配空间
            HC[i]=(char*)malloc((n-start)*sizeof(char)) ;
            strcpy(HC[i],&cd[start]);//从cd复制编码串到HC中 
        } 
        free(cd);//释放空间 
    }
    
    void Output_HuffmanCoding(char a[],char b[],int m,int n,HuffmanCode HC){
        //输出Huffman编码
        int i,j;
        printf("字符串转换成的Huffman编码如下:
    ");
        for(i=0;i<m;i++){
            for(j=0;j<m;j++){
                if(a[i]==b[j]){
                    cout<<HC[j+1]<<"	";
                }
            }
        } 
        cout<<endl;
    } 
    
    void HuffmanDecoding(int n,char b[],HuffmanTree HT){
        //对编码的二进制串进行解码 
        int m=2*n-1;
        int i=m;
        char c;
        printf("
    请输入一串编码:
    ");
        cin>>c;
        while((c=='0')||(c=='1')){//判断是否是合法字符 
            if(c=='0')
                i=HT[i].lchild;//继续向左查找
            else
                i=HT[i].rchild;//继续向右查找
            if(HT[i].lchild==0){//直到分支的末端 
            printf("
    所得译码为:
    ");
                printf("%c
    ",b[i-1]);//输出对应的符合
                i=m;//重新开始找下一个 
            } 
            cin>>c;
        } 
        printf("
    ");
    } 
    
    int main(){
        HuffmanTree HTree;
        HuffmanCode HCode; 
        char a[100],b[100]; //a为输入的字符串 
        int i=0,j=0,len=0,n=0,*w;
        printf("请输入任意一组字符:
    ");
        gets(a);
        len=strlen(a);
        for(i=0;i<len;i++){
            for(j=0;j<i;j++){
                if(i<len&&a[j]==a[i]){
                    i++;
                    j=-1;
                } 
            }
            if(i<len){
                b[n]=a[i];
                n++;
            }
        }
        w=(int*)malloc((n+1)*sizeof(int));
        for(i=1;i<=n;i++){ //初始化 
            w[i]=0;
        } 
        cout<<"----"<<endl;
        Calculate_weight(a,b,len,n,w);//计算不同字符的个数 
        cout<<"---"<<endl;
        HuffmanCoding(HTree,HCode,w,n);//构造Huffman二叉树HT 
        output_code_info(b,HCode,n);
        printf("
    Huffman各个字符的详细编码如下:
    ");
        printf("编码表:	编码频度:
    ");
        for(i=1;i<=n;i++){
            cout<<b[i-1]<<":"<<HCode[i]<<"	"<<A[i]+1<<endl;
        }
        Output_HuffmanCoding(a,b,len,n,HCode);//输出Huffman编码
        HuffmanDecoding(n,b,HTree);//对编码的二进制串进行解码 
        return 0;
    } 
  • 相关阅读:
    Attach Files to Objects 将文件附加到对象
    Provide Several View Variants for End-Users 为最终用户提供多个视图变体
    Audit Object Changes 审核对象更改
    Toggle the WinForms Ribbon Interface 切换 WinForms 功能区界面
    Change Style of Navigation Items 更改导航项的样式
    Apply Grouping to List View Data 将分组应用于列表视图数据
    Choose the WinForms UI Type 选择 WinForms UI 类型
    Filter List Views 筛选器列表视图
    Make a List View Editable 使列表视图可编辑
    Add a Preview to a List View将预览添加到列表视图
  • 原文地址:https://www.cnblogs.com/zhying99/p/11081834.html
Copyright © 2011-2022 走看看