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");
    }

  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/DonAndy/p/6071719.html
Copyright © 2011-2022 走看看