• 哈夫曼编码--贪心策略


    哈夫曼编码还是在暑假时候看的,那时候并没有看懂因为比较菜(虽然现在也是很菜的),在《趣学算法》一书中这个问题讲解十分到位,我这篇博客真的是难以望其项背,只能对其进行一点借鉴和摘抄吧

    哈夫曼编码是一棵树,权值越大的节点越靠近树根,越小的节点就越远离树根,从他的定义来看,首先想到的应该是贪心策略吧,没错就是贪心算法

    虽然说是贪心算法,但是还要知道它 的实现方式啊,他的贪心策略是:每次从树的集合中取出没有双亲且权值最小的两棵树作为左右子树,并合并他们

    步骤 :

      1 :确定合适的数据结构(要知道他的左右子树,双亲,权值)

      2:初始化,构造n颗节点为n的字符单节点树集合T={t1,t2,t3,t4···········tn},并且每棵树只有树根

      3:如果集合中只剩下一棵树,那么哈夫曼树就构造成功,直接跳转到步骤6,否则就是从集合中继续拿出没有双亲的左右子树x,y,并将它们合并到一颗z树中,

        z的权值为左右子树权值之和

      4:从T集合中删除x,y 把新树z加入到集合T中

      5:重复步骤3~4

      6:约定左分支上的编码都是0,有分支上的编码都是1,从叶子节点开始逆序求出树的编码

    图解:(这儿就直接调用这本书上的图片吧,是在太懒不想画图)

      

    代码的实现:

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXBIT 100
    #define MAXVALUE 10000
    #define MAXLEAF 30
    #define MAXNODE MAXLEAF*2-1
    typedef struct{
        double weight;
        int parent;
        int lchild;
        int rchild;
        char value;
    }HNodeType;//¶¨ÒåµÄÊǽڵã·Ö±ðÓÐȨÖØ£¬Ë«Ç׽ڵ㣬×óÓÒº¢×Ó£¬»¹Óдú±íµÄ×Ö·û 
    typedef struct{
        int bit[MAXBIT];
        int start;
    }HCodeType;//ÕâÊDZàÂë½á¹¹Ìå 
    HNodeType HuffNode[MAXNODE];//½Úµã½á¹¹ÌåÊý×é 
    HCodeType HuffCode[MAXLEAF];//±àÂë½á¹¹ÌåÊý×é 
    /*½ÓÏÂÀ´¿ªÊ¼¹¹Ôì¹þ·òÂüÊ÷*/
    void HuffmanTree(HNodeType HuffNode[MAXNODE],int n)
    {
        /*i,jÊÇÑ­»·±äÁ¿£¬m1,m2ÊÇ×îСµÄȨֵ
        x1,x2Êǹþ·òÂüÊ÷×îСȨֵ¶ÔÓ¦µÄÐòºÅ
        */
        int i,j,x1,x2;
        double m1,m2;
    //    ³õʼ»¯½Úµã 
        for(i=0;i<2*n-1;i++)
        {
            HuffNode[i].lchild=-1;
            HuffNode[i].parent=-1;
            HuffNode[i].rchild=-1;
            HuffNode[i].weight=0;
        }
        for(i=0;i<n;i++)
        {
            cout<<"Please enter the value of every Node "<<i+1<<endl;
            cin>>HuffNode[i].value>>HuffNode[i].weight;
        }
    //    ¹¹Ôì¹þ¸¥ÂüÊ÷
        for(i=0;i<n-1;i++)
        {//Ҫѭ»·n-1´Î 
            m1=m2=MAXVALUE;
            x1=x2=0;
        //ÏÂÃ濪ʼÕÒ×îСµÄÁ½¸öÖµ
            for(j=0;j<n+i;j++)
            {
                if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1)
                {
                    m2=m1;
                    x2=x1;
                    m1=HuffNode[j].weight;
                    x1=j;
                }
                else if(HuffNode[j].weight<m2&&HuffNode[j].parent==-1)
                {
                    m2=HuffNode[j].weight;
                    x2=j;
                }
            }
            HuffNode[x1].parent=n+i;
            HuffNode[x2].parent=n+i;
            HuffNode[n+i].weight=m1+m2;
            HuffNode[n+i].lchild=x1;
            HuffNode[n+i].rchild=x2;
            cout<<"x1.weight and x2.weight in round "<<i+1<<"	"
                <<HuffNode[x1].weight<<"	"<<HuffNode[x2].weight<<endl;//ÓÃÓÚ²âÊÔ
             
        }
    }
    void HuffmanCode(HCodeType HuffCode[MAXLEAF],int n)
    {
        HCodeType cd;
        int i,j,c,p;
        for(i=0;i<n;i++)
        {
            cd.start=n-1;
            c=i;
            p=HuffNode[c].parent;
            while(p!=-1)
            {
                if(HuffNode[p].lchild==c)
                    cd.bit[cd.start]=0;
                else 
                    cd.bit[cd.start]=1;
                cd.start--;
                c=p;
                p=HuffNode[c].parent;
            }
            for(j=cd.start+1;j<n;j++)
                HuffCode[i].bit[j]=cd.bit[j];
            HuffCode[i].start=cd.start;
        }
    }
    int main()
    {
        int i,j,n;
        cout<<"Please enter n"<<endl;
        cin>>n;
        HuffmanTree(HuffNode,n);
        HuffmanCode(HuffCode,n);
        for(i=0;i<n;i++)
        {
            cout<<HuffNode[i].value<<": Huffman Code is: ";
            for(j=HuffCode[i].start+1;j<n;j++)
            {
                cout<<HuffCode[i].bit[j];
            }
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    静态成员 执行顺序
    排序之插入排序
    结构体字节对齐问题
    建模基础&UML
    C#中隐藏(new)和方法重载(overide)的区别
    培训记录
    C笔记
    用例
    .NET架构
    C#格式化日期
  • 原文地址:https://www.cnblogs.com/acmblog/p/9629736.html
Copyright © 2020-2023  润新知