• 赫夫曼编码


    已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试编写算法求其赫夫曼编码

    1 #include<iostream>
    2 using namespace std;
    3 //#include "HTNode.h"
    4 typedef char **HuffmanCode;
    5 typedef struct
    6 {
    7     int weight;
    8     int parent,lchild,rchild;
    9 }HTNode,*HuffmanTree;
    void Select(HuffmanTree &HT,int n,int &s1,int &s2)
    {
        int i;
        int min=0;
        for(i=1;i<=n;++i)
        {
            if(HT[i].parent==0)
            {
                if(min==0)
                {
                    min=HT[i].weight;min++;s1=i;
                }            
                if(HT[i].weight<min)
                {
                    min=HT[i].weight;s1=i;
                }
            }
        }
    
    
        min=0;
        for(i=1;i<=n;++i)
        {
            if((HT[i].parent==0)&&(i!=s1))
            {
                if(min==0)
                {min=HT[i].weight;min++;s2=i;}
                if(HT[i].weight<min)
                {min=HT[i].weight;s2=i;}
            }
        }
        if(s2<s1) //保证s1的下标值小与s2实现左右子树的大小对称
        {
            s1=s1+s2;
            s2=s1-s2;
            s1=s1-s2;
        } 
    }
    
    
    void CreatHuffmanTree(HuffmanTree &HT,int n)
    { 
        //构造赫夫曼树
        int i,m,s1,s2;
        if(n<=1)return;
        m=2*n-1;
        HT=new HTNode[m+1];//树的信息储存在数组中
        for(i=1;i<=m;++i)
        {
            HT[i].parent=0;
            HT[i].lchild=0;
            HT[i].rchild=0;
        }
        cout<<"请输入8个权值:
    ";
        for(i=1;i<=n;++i)
        cin>>HT[i].weight;//输入树叶子结点的权值
        for(i=n+1;i<=m;++i)
        {
            //在HT数组中选择两个其双亲域为0且权值最小的结点,并返回它们的下标S1,S2
            Select(HT,i-1,s1,s2);
    
            cout<<"s1="<<s1<<"s2="<<s2<<endl;
            HT[s1].parent=i;
            HT[s2].parent=i;
            HT[i].lchild=s1;
            HT[i].rchild=s2;
            HT[i].weight=HT[s1].weight+HT[s2].weight;
        }
    }
    
    void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
    {
        int start,i,c,f;
        HC=new char*[n+1];
        char *cd=new char[n];
        cd[n-1]='';
        for(i=1;i<=n;++i)
        {
            start=n-1;
            c=i;f=HT[i].parent;
            while(f!=0)
            {
                --start;
                if(HT[f].lchild==c) cd[start]='0';
                else cd[start]='1';
                c=f;f=HT[f].parent;
            }
            HC[i]=new char[n-start];
            strcpy(HC[i],&cd[start]);
        }
        delete cd;
    }
    int main()
    {
        HuffmanTree HT;
        HuffmanCode HC;
        int i,n=8;
        CreatHuffmanTree(HT,n);
        CreatHuffmanCode(HT,HC,n);
        for(i=1;i<=n;i++)
            cout<<""<<i<<"个字符的编码"<<HC[i]<<endl;
        return 0;
    }

    /*
    请输入8个权值:
    5 29 7 8 14 23 3 11
    s1=1 s2=7
    s1=3 s2=4
    s1=8 s2=9
    s1=5 s2=10
    s1=6 s2=11
    s1=2 s2=12
    s1=13 s2=14
    第1个字符的编码0110
    第2个字符的编码10
    第3个字符的编码1110
    第4个字符的编码1111
    第5个字符的编码110
    第6个字符的编码00
    第7个字符的编码0111
    第8个字符的编码010
    Press any key to continue
    */

  • 相关阅读:
    Hibernate的游离态与持久态转换
    怎样区分直连串口线和交叉串口线?
    JAVA 内存泄露的理解
    leetcode第一刷_Validate Binary Search Tree
    Java程序猿的JavaScript学习笔记(8——jQuery选择器)
    Android二维码开源项目zxing用例简化和生成二维码、条形码
    Android Service 服务(一)—— Service
    一个简单的文本编辑器。(是在DEV C++下写的)
    我的Hook学习笔记
    ios网络学习------8 xml格式数据的请求处理 用代码块封装
  • 原文地址:https://www.cnblogs.com/Lijcyy/p/13836809.html
Copyright © 2020-2023  润新知