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;
    } 
  • 相关阅读:
    mysql关联查询
    文本框,下拉框,单选框只读状态属性
    sql索引实例
    sql视图实例
    SQL触发器实例
    存储过程实例
    sql 、linq、lambda 查询语句的区别
    LINQ中的一些查询语句格式
    面试宝典
    SQL常用语句
  • 原文地址:https://www.cnblogs.com/zhying99/p/11081834.html
Copyright © 2011-2022 走看看