zoukankan      html  css  js  c++  java
  • Huffman Tree

    哈弗曼树定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。

    哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

    #include<iostream>
    #include<iomanip>
    using namespace std;
    const int n=7; //maxn表示叶子数目
    const int m=2*n-1; //m为森林中树的数
    const int maxValue=3555; //最大权值
    struct TreeNode //哈夫曼树中的一个结点
    { float weight; //权值
    int parent; //双亲
    int lchild,rchild; //左孩子、右孩子
    };

    struct hacode //哈弗曼编码
    { int bits[n+1]; //哈弗曼编码
    int start; //编码的存放位置
    char ch; //所对应的字符
    };

    TreeNode haffTreeNode[m+1];
    hacode code[n+1];

    void CreatHaffTreeNode() //建立哈夫曼树
    {
    int i,j,p1,p2; float s1,s2;
    for(i=1;i<=2*n-1;i++)
    {
    haffTreeNode[i].parent=0;
    haffTreeNode[i].lchild=0;
    haffTreeNode[i].rchild=0;
    haffTreeNode[i].weight=0;
    }
    cout<<"请输入"<<n<<"个权值"<<endl;
    for(i=1;i<=n;i++)
    cin>>haffTreeNode[i].weight; //输入权值
    for(i=n+1;i<=2*n-1;i++) //进行N-1次合并,n-1个非叶子节点
    { p1=p2=0; //p1,p2分别指向两个权值最小的值的位置
    s1=s2=maxValue; //s1,s2代表两个最小权值
    for(j=1;j<=i-1;j++){ //选两个最小值
    if(haffTreeNode[j].parent==0) //该权值还没有选中
    if(haffTreeNode[j].weight<s1)
    {
    s2=s1;
    s1=haffTreeNode[j].weight;
    p2=p1;
    p1=j;
    }
    else if(haffTreeNode[j].weight<s2)
    {
    s2=haffTreeNode[j].weight;
    p2=j;
    }
    }//以下为合并
    haffTreeNode[p1].parent=i;
    haffTreeNode[p2].parent=i;
    haffTreeNode[i].lchild=p1;
    haffTreeNode[i].rchild=p2;
    haffTreeNode[i].weight=haffTreeNode[p1].weight+haffTreeNode[p2].weight;
    }

    }

    //带权路径长度:哈法曼树的除叶子节点,剩余的节点的权值之和
    float WPL()
    {
    float wpl=0;
    for(int i=2*n-1;i>=n+1;i--)
    wpl=wpl+haffTreeNode[i].weight;
    return wpl;
    }

    void HuffCode() //哈弗曼编码
    {
    hacode cd;
    int c,p;
    for(int i=1;i<=n;i++)
    {
    cd.start=n+1;
    cd.ch=96+i; //第一个树叶对应字母a,其余依此类推
    c=i;
    p=haffTreeNode[i].parent;
    while(p!=0)
    {
    cd.start--;
    if(haffTreeNode[p].lchild==c)
    cd.bits[cd.start]=0;
    else
    cd.bits[cd.start]=1;
    c=p;
    p=haffTreeNode[p].parent;
    }
    code[i]=cd;
    }
    for(int i=1;i<=n;i++)
    {

    cout<<"字符"<<code[i].ch<<"的权值为:"<<haffTreeNode[i].weight<<setw(5)<<" 编码为:";
    for(int j=code[i].start;j<=n;j++)
    cout<<code[i].bits[j]<<" ";
    cout<<endl;
    }
    }
    void TransCode() //哈弗曼译码
    {
    int i=m;
    char b;
    cout<<"请输入二进制编码串(以非0,1结束)"<<endl;
    cin>>b;
    while((b=='0')||(b=='1'))
    {
    if(b=='0')
    i=haffTreeNode[i].lchild;
    else
    i=haffTreeNode[i].rchild;
    if(haffTreeNode[i].lchild==0)
    {
    cout<<code[i].ch;
    i=m;
    }
    cin>>b;
    }
    }
    void main()
    {
    CreatHaffTreeNode(); //建立哈夫曼树
    float length=WPL();
    cout<<"长度是:"<<length<<endl;
    HuffCode(); //实现哈弗曼编码
    TransCode(); //进行哈弗曼译码
    cout<<endl;
    system("pause");
    }

  • 相关阅读:
    2017第17周四当前工作中困境与挑战思考
    2017第17周三
    2017第17周二
    最小可行产品
    《穷查理宝典》中三条最重要的学习方法
    机场打车有感
    2017第15周五
    2017第15周四
    三条经济学原理帮你做出正确的选择
    Mac通过安装Go2Shell实现“在当前目录打开iTerm2”
  • 原文地址:https://www.cnblogs.com/DonAndy/p/6071719.html
Copyright © 2011-2022 走看看