zoukankan      html  css  js  c++  java
  • 算法分析设计实践——哈夫曼编码

    问题:

    设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。

    解析:

    实数w1,w2,···,wt且 w1<=w2<=···<=wt           

    (1)连接w1,w2为权的两片树叶,得一分支点,其权为w1+w2 ;

    (2)在w1+w2, w3+···+wt中选出两个最小的权,连接它们对应的顶点(不一定都是树叶),得分支点及所带的权;

    (3)重复(2),直到形成t – 1个分支点,t片树叶为止。

    构建好哈夫曼树之后,哈夫曼树的左边分支置为0,右边分支置为1,就可以形成每个字母的不等长编码。

    设计:

    void SetHuffTree(node HuffTree[],int w[] , char ch[], int n)
    {
        for (int i = 0; i < 2 * n - 1; ++i)
        {
            HuffTree[i].parent = -1;
            HuffTree[i].lchild = -1;
            HuffTree[i].rchild = -1;
        }
        for (int i = 0; i < n; ++i)
        {
            HuffTree[i].weight = w[i];
            HuffTree[i].ch = ch[i];
        }
        for (int i = n; i < 2 * n - 1; ++i)
        {
            int a = 0, b = 0;
            select(HuffTree, &a, &b, i);
            HuffTree[a].parent = i;
            HuffTree[b].parent = i;
            HuffTree[i].weight = HuffTree[a].weight + HuffTree[b].weight;
            HuffTree[i].lchild = a;
            HuffTree[i].rchild = b;
        }
    
    }

    分析:

    时间复杂度:O(n * n)

    源码:

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #include<cctype>
    #include<time.h>
    #define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define mem(a,x) memset(a,x,sizeof(a))
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid + 1,r
    #define P pair<int,int>
    #define ull unsigned long long
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 10;
    const ll mod = 998244353;
    const int inf = 0x3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-7;
    
    int n;
    struct node
    {
        int weight;
        char ch;
        int lchild, rchild, parent;
    }HuffTree[maxn * 2];
    
    int w[maxn];
    char ch[maxn];
    void select(node HuffTree[], int* a, int *b ,  int n)
    {
        int weight = inf;
        for (int i = 0; i < n; ++i)
        {
            if (HuffTree[i].parent != -1)
                continue;
            else
            {
                if (HuffTree[i].weight < weight)
                {
                    weight = HuffTree[i].weight;
                    *a = i;
                }
            }
        }
        weight = inf;
        for (int i = 0; i < n; ++i)
        {
            if (HuffTree[i].parent != -1 || i == *a)
                continue;
            else
            {
                if (HuffTree[i].weight < weight)
                {
                    weight = HuffTree[i].weight;
                    *b = i;
                }
            }
        }
        int temp;
        if (HuffTree[*a].lchild < HuffTree[*b].lchild)
        {
            temp = *a;
            *a = *b;
            *b = temp;
            //swap(*a, *b);
        }
    }
    
    
    void SetHuffTree(node HuffTree[],int w[] , char ch[], int n)
    {
        for (int i = 0; i < 2 * n - 1; ++i)
        {
            HuffTree[i].parent = -1;
            HuffTree[i].lchild = -1;
            HuffTree[i].rchild = -1;
        }
        for (int i = 0; i < n; ++i)
        {
            HuffTree[i].weight = w[i];
            HuffTree[i].ch = ch[i];
        }
        for (int i = n; i < 2 * n - 1; ++i)
        {
            int a = 0, b = 0;
            select(HuffTree, &a, &b, i);
            HuffTree[a].parent = i;
            HuffTree[b].parent = i;
            HuffTree[i].weight = HuffTree[a].weight + HuffTree[b].weight;
            HuffTree[i].lchild = a;
            HuffTree[i].rchild = b;
        }
    
    }
    
    
    void SetHuffCode(node HuffTree[], int n)
    {
        string s = "";
        for (int i = 0; i < n; ++i)
        {
            s = "";
            int j = i;
            while (HuffTree[j].parent != -1)
            {
                int k = HuffTree[j].parent;
                if (j == HuffTree[k].lchild)
                {
                    s += "0";
                }
                else
                {
                    s += "1";
                }
                j = HuffTree[j].parent;
            }
            cout << "字符" << HuffTree[i].ch << "的编码" << endl;
            for (int i = s.size() - 1; i >= 0; --i)
            {
                cout << s.at(i);
            }
            cout << endl;
        }
    }
    
    int main()
    {
        scanf("%d", &n);
        scanf("%s", ch);
        for (int i = 0; i < n; ++i)
        {
            scanf("%d", &w[i]);
        }
        
        SetHuffTree(HuffTree, w, ch , n);
        SetHuffCode(HuffTree, n);
        return 0;
    }
    完整代码

    https://github.com/BambooCertain/Algorithm.git

  • 相关阅读:
    spring学习(十七)--annotion注解
    spring学习(十六)--spring方式实现工程初始化配置
    spring学习(十五)--自己实现BeanFactory
    JDBC使用SPI机制解析
    SPI机制
    spring学习(十三)--自己实现SpringServletContainerInitializer
    cetnos基本操作
    CentOS基本命令
    面向对象的双下方法
    Flask数据连接池 DBUtils
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/12920472.html
Copyright © 2011-2022 走看看