7-1 哈夫曼树哈夫曼编码

7-1 哈夫曼树哈夫曼编码

输入一组整型权值,构建哈夫曼树,实现哈夫曼编码,并输出带权路径长度。

输入格式:

第一行输入叶子结点个数,接着依次输入权值。

输出格式:

输出哈夫曼编码,输出带权路径长度。

输入样例:

在这里给出一组输入。例如:

8
5 29 7 8 14 23 3 11

输出样例:

在这里给出相应的输出。例如:

5编码为0001
29编码为10
7编码为1110
8编码为1111
14编码为110
23编码为01
3编码为0000
11编码为001
WPL:271


#include<iostream>
#include<string>
#include <string.h>
#include <stdio.h>
using namespace std;

typedef struct{
    int weight;     //权重
    int parent,lchild,rchild;  //节点双亲,左右孩子
}HTNode,*HuffmanTree;   //动态分配数组存哈夫曼树

int Select(HuffmanTree &HT, int n)
{
    int p=0;
    for(int i=1;i<=n;i++)
    {
        if(HT[i].parent==0 && (p==0||HT[i].weight < HT[p].weight))
        {
            p=i;
        }
    }
    return p;
}

void CreateHuffmanTree(HuffmanTree &HT,int n)
{
    if(n<=1) return;
    int m = 2*n - 1;
    HT = new HTNode[m+1];
    for(int i = 1; i<=m ;i++)   //初始化下标为0
    {
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
    }
    for(int i = 1; i <= n; i++)
    {
        cin>>HT[i].weight;  //输入节点
    }

 for(int i=n+1; i <= m ;i++) //n-1次选择
 {
   //选择双亲为0,权值最小的节点,返回他们的序号s1,s2
     int s1 = Select(HT, i-1);
        HT[s1].parent = i;     //删除s1,s2,双亲改为i
     int s2 = Select(HT, i-1);
        HT[s2].parent = i;
   //s1,s2作为i的孩子
    HT[i].lchild = s1;
    HT[i].rchild = s2;
   //i的权值等于孩子的权值之和
    HT[i].weight = HT[s1].weight + HT[s2].weight;
  }
}

typedef char **HuffmanCode;
void CreateHuffmanCode( HuffmanTree HT,HuffmanCode &HC , int n)
{
   HC = new char*[n+1];      //编码数组
   char cd[n];        //临时编码数组
   cd[n-1] = '\0';          //结束符
  for(int i = 1; i<=n ;i++)
  {
      int start = n-1;  //开始指向最后
      int c = i;
      int f = HT[i].parent;  //f指向c的双亲
      while( f!=0 )
      {
          --start;  //回溯

          if(HT[f].lchild == c)
              cd[start] = '0';
          else
              cd[start] = '1';
          //回溯
          c = f;
          f = HT[f].parent;
      }
      HC[i] = new char[n-start];
      strcpy(HC[i] , &cd[start]);
  }
    //delete cd;
}


void show(HuffmanTree HT,HuffmanCode &HC , int n)
{
    int wpl = 0;
    for(int i=1;i<=n;i++)
    {
       string s = HC[i];
       cout<<HT[i].weight<<"编码为"<<HC[i]<<endl;
       wpl+=HT[i].weight*s.length();
    }
    cout<<"WPL:"<<wpl;
}
int main()
{
    int n;
    HuffmanTree HT = new HTNode;
    cin>>n;
    if(n==1||n==0)
    {
        cout<<"error";
         return 0;
    }
    CreateHuffmanTree(HT,n);
    HuffmanCode HC;
    CreateHuffmanCode(HT ,HC,n );
    show(HT ,HC,n);
    return 0;
}

 

 
posted @ 2022-11-23 16:58  旺旺大菠萝  阅读(92)  评论(0编辑  收藏  举报