zoukankan      html  css  js  c++  java
  • 哈弗曼编码

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    
    #define MAXNUM 10
    #define MAXBIT 10
    #define MINWEIGHT 1000000
    
    typedef struct
    {
        char value;                          // 输入结点代号,如A, B, C...
         int  parent;                        /* 父子关系用下标值进行关联 */
        int  lchild;
        int  rchild;
        int  weight;                         // 自身权重
    }HTNODE;
    typedef struct
    {
        char bit[MAXBIT];                    // 存储编码
    }HTCODE;
    /******************************************************************************************/
    
    void Init(int &n, HTNODE *HTNode)
    {
        cout << "Input the Number of Object, n = "; cin >> n;
        for(int i = 0; i < n; i++)
        {
            HTNode[i].value = 65 + i;                        // 默认代号A, B, C...
            HTNode[i].parent = -1;
            HTNode[i].lchild = -1;
            HTNode[i].rchild = -1;
            cout << "weight[" << i << "] = ";
            cin >> HTNode[i].weight;
        }
        int m = 2 * n - 1;
        for(int i = n; i < m; i++)
        {
            HTNode[i].value = '*';                           // 合成结点代号
            HTNode[i].parent = -1;
            HTNode[i].lchild = -1;
            HTNode[i].rchild = -1;
            HTNode[i].weight = 0;
        }
    }
    void Select(int &fstSmallest, int &sndSmallest, HTNODE *HTNode, int i)
    {
        fstSmallest = -1;
        sndSmallest = -1;
        int fstSWeight = MINWEIGHT;
        int sndSWeight = MINWEIGHT;
        for(int k = 0; k < i; k++)
        {
            if(HTNode[k].parent == -1)
            {
                if(HTNode[k].weight <= fstSWeight)
                {
                    sndSmallest = fstSmallest;
                    sndSWeight = fstSWeight;
                    fstSmallest = k;
                    fstSWeight = HTNode[k].weight;
                }
                else if(HTNode[k].weight>fstSWeight && HTNode[k].weight<sndSWeight)
                {
                    sndSmallest = k;
                    sndSWeight = HTNode[k].weight;
                }
            }
        }
    }
    void BuildHuffmanTree(int n, HTNODE *HTNode)
    {
        int m = 2 * n - 1;                                // 可计算出哈夫曼树结点总数
        int fstSmallest, sndSmallest;                     // 分别标记下标值
        for(int i = n; i < m; i++)
        {
            Select(fstSmallest, sndSmallest, HTNode, i);
            HTNode[fstSmallest].parent = i;
            HTNode[sndSmallest].parent = i;
            HTNode[i].lchild = fstSmallest;
            HTNode[i].rchild = sndSmallest;
            HTNode[i].weight = HTNode[fstSmallest].weight + HTNode[sndSmallest].weight;
        }
    }
    void PrintHuffmanTree(int n, HTNODE *HTNode)
    {
        int m = 2 * n - 1;
        for(int i = 0; i < m; i++)
        {
            cout << "
    i = " << i;
            printf("  value = %c", HTNode[i].value);
            printf("  parent = %2d", HTNode[i].parent);
            printf("  lchild = %2d", HTNode[i].lchild);
            printf("  rchild = %2d", HTNode[i].rchild);
            printf("  weight = %2d", HTNode[i].weight);
            cout << endl;
        }
    }
    void HuffmanCoding(int n, HTNODE *HTNode, HTCODE *HTCode)
    {
        int j, start;
        char Tbit[MAXBIT];
        for(int i = 0; i < n; i++)                                   /* 编码i结点 */
        {
            start = MAXBIT-1;
            int temp_child = i;                                      // 临时孩子
            int temp_parent = HTNode[i].parent;                      // 临时父亲
            while(temp_parent != -1)
            {
                cout << "temp_child = " << temp_child;               // Debug 编码过程
                cout << "  temp_parent = " << temp_parent << endl;   // Debug 编码过程
                if(HTNode[temp_parent].lchild == temp_child)
                    Tbit[--start] = '0';
                else Tbit[--start] = '1';
                temp_child = temp_parent;
                temp_parent = HTNode[temp_child].parent;
            }
            strcpy(HTCode[i].bit, &Tbit[start]);
            cout << "bit = " << HTCode[i].bit << endl;               // Debug 编码过程
        }
    }
    void HuffmanDecoding(int n, HTNODE *HTNode)
    {
        int it, flag = 1;
        int m = 2 * n - 1;
        char str[MAXBIT], *p;
        printf("
    Input the String, str = ");
        scanf("%s", str); p = str;
    
        for(int i = 0; i < m; i++)                                   // 先定位到根节点
            if(HTNode[i].parent == -1)
            { it = i; break; }
        while(*p != '')
        {
            if(HTNode[it].lchild==-1 && HTNode[it].rchild==-1)       // 编码串过长
            { flag = -1; break; }
            if(p[0] == '0')
                it = HTNode[it].lchild;
            else it = HTNode[it].rchild;
            p++;
        }
        if(HTNode[it].lchild!=-1 && HTNode[it].rchild!=-1)           // 编码串过短
        { flag = -1; }
        if(flag == -1) printf("Input String is Error!
    ");
        else printf("Decoding Result is: %c
    ", HTNode[it].value);
    }
    /******************************************************************************************/
    
    int main()
    {
        int n;
        HTNODE HTNode[MAXNUM];                     // MAXNUM表示哈夫曼树结点数上限
        HTCODE HTCode[MAXNUM];
        Init(n, HTNode);
        BuildHuffmanTree(n, HTNode);
        PrintHuffmanTree(n, HTNode);
        HuffmanCoding(n, HTNode, HTCode);
        HuffmanDecoding(n, HTNode);
        return 0;
    }

  • 相关阅读:
    Asp.net分页控件AspNetPager的使用(DataList和Reapter结合Linq的编辑与删除)
    Zend Framework使用Extjs进行数据库交互和分页
    课程设计之(struts2+Hibernate)航空订票系统
    课程设计之(ZendFrameWrok)构建的航空订票系统网站
    Ubuntu10.10 Zend FrameWork配置及helloworld显示
    ExtJs、Struts2、Hibernate3.2登录页面的简单实现
    Asp.net的FileUpload控件的文件上传与Extjs文件上传的简单Demo
    学习linux的一些网络资源
    100条超搞笑的“雷人”QQ/MSN 签名
    超难的75道逻辑思维题
  • 原文地址:https://www.cnblogs.com/1203ljh/p/4650590.html
Copyright © 2011-2022 走看看