码迷,mamicode.com
首页 > 其他好文 > 详细

5678: 数据结构实验:哈夫曼树和编码

时间:2019-05-09 22:02:18      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:man   def   包含   ott   结构   打印   using   weight   nbsp   

描述

 

当用 n 个结点(都做叶子结点且都有各自的权值)试图构建一棵树时,如果构建的这棵树的带权路径长度最小,称这棵树为“最优二叉树”,有时也叫“赫夫曼树”或者“哈夫曼树”。

现给定若干权值,请构建一棵哈夫曼树,并输出各个权值对应的哈夫曼编码长度。

哈夫曼树中的结点定义如下:

//哈夫曼树结点结构

typedef struct

{

    int weight;//结点权重

    int parent, left, right;//父结点、左孩子、右孩子在数组中的位置下标

}HTNode, *HuffmanTree;

//动态二维数组,存储哈夫曼编码

typedef char ** HuffmanCode;

部分代码已完成,请补充完整,提交时请勿包含给定代码。

 

//打印哈夫曼编码的函数
void PrintHuffmanCode(HuffmanCode htable, int *w, int n)
{
    printf("Huffman code:\n");
    for(int i = 1; i <= n; i++)
        printf("%d(%d)\n",w[i-1], strlen(htable[i]));
}
int main()
{
    int w[100], n, i;
    scanf("%d", &n);
    for(i=0;i<n;i++)
        scanf("%d", &w[i]);
    HuffmanTree htree;
    HuffmanCode htable;
    CreateHuffmanTree(htree, w, n);
    HuffmanCoding(htree, htable, n);
    PrintHuffmanCode(htable,w, n);
    return 0;
}

输入

 

输入数据第一行为n(不超过100),接下来有n个正整数,表示权值。

 

输出

 

按照输入权值顺序输出相应的哈夫曼编码的长度,格式见样例。

 

样例输入

样例输出

代码:

技术图片
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 typedef struct
  5 {
  6     int weight;//结点权重
  7     int parent, left, right;//父结点、左孩子、右孩子在数组中的位置下标
  8 }HTNode, *HuffmanTree;
  9 typedef char ** HuffmanCode;
 10 
 11 void select(HuffmanTree htree,int n, int *s1,int *s2){
 12     int minn;
 13     for(int i=1;i<=n;i++){
 14         if((htree)[i].parent==0){ //如果此结点的父亲没有,那么把结点号赋值给 min,跳出循环
 15             minn=i;
 16             break;
 17         }
 18     }
 19     for(int i=1;i<=n;i++){   //找出权值最小的
 20         if((htree)[i].parent==0){
 21             if((htree)[i].weight<(htree)[minn].weight){
 22                 minn=i;
 23             }
 24         }
 25     }
 26     *s1=minn;  //编号
 27     for(int i=1;i<=n;i++){
 28         if((htree)[i].parent==0&&i!=(*s1)){ //如果此结点的父亲没有,那么把结点号赋值给 min,跳出循环
 29             minn=i;
 30             break;
 31         }
 32     }
 33     for(int i=1;i<=n;i++){
 34         if((htree)[i].parent==0&&i!=(*s1)){
 35             if((htree)[i].weight<(htree)[minn].weight){
 36                 minn=i;
 37             }
 38         }
 39     }
 40     *s2=minn;   //找出两个编号最小的
 41 }
 42 
 43 void CreateHuffmanTree(HuffmanTree &htree,int w[],int n){
 44     if(n<=1) return; // 如果只有一个编码就相当于 0
 45     int m=2*n-1;  //哈夫曼树度为2或为0 总结点树为2*n-1;
 46     int s1,s2; //s1 和 s2 为两个当前结点里,要选取的最小权值的结点
 47     htree=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
 48     for(int i=1;i<=n;i++){     //1--n号存放叶子结点,初始化叶子结点,结构数组来初始化每个叶子结点
 49         (htree)[i].weight=w[i-1];
 50         (htree)[i].parent=0;
 51         (htree)[i].left=0;
 52         (htree)[i].right=0;
 53     }
 54     for(int i=n+1;i<=m;i++){  //非叶子结点的初始化
 55         (htree)[i].weight=0;
 56         (htree)[i].parent=0;
 57         (htree)[i].left=0;
 58         (htree)[i].right=0;
 59     }
 60     for(int i=n+1;i<=m;i++){   //创建非叶子结点,建哈夫曼树
 61         select(htree, i-1, &s1, &s2);  //再前面有权值里面选出两个最小的构建二叉树
 62         (htree)[s1].parent=i;
 63         (htree)[s2].parent=i;
 64         (htree)[i].left=s1;
 65         (htree)[i].right=s2;
 66         (htree)[i].weight=(htree)[s1].weight+(htree)[s2].weight;
 67     }
 68 }
 69 
 70 void HuffmanCoding(HuffmanTree &htree,HuffmanCode &htable,int n){
 71     htable=(HuffmanCode)malloc((n+1)*sizeof(char*));
 72     char *cd = (char *)malloc(n*sizeof(char));
 73     cd[n-1]=\0;
 74     for(int i=1;i<=n;i++){   //从叶子节点开始
 75         //从叶子结点出发,得到的哈夫曼编码是逆序的,需要在字符串数组中逆序存放
 76         int start=n-1;
 77         int c=i;
 78         int j=htree[i].parent;
 79         while(j!=0){
 80             // 如果该结点是父结点的左孩子则对应路径编码为 0,否则为右孩子编码为 1
 81             if(htree[j].left==c){
 82                 cd[--start]=0;
 83             }
 84             else cd[--start]=1;
 85             c=j;
 86             j=htree[j].parent;
 87         }
 88         //跳出循环后,cd 数组中从下标 start 开始,存放的就是该结点的哈夫曼编码
 89         htable[i] = (char *)malloc((n-start)*sizeof(char));
 90         strcpy(htable[i],&cd[start]);
 91     }
 92     free(cd);
 93 }
 94 
 95 void PrintHuffmanCode(HuffmanCode htable, int *w, int n)
 96 {
 97     printf("Huffman code:\n");
 98     for(int i = 1; i <= n; i++)
 99         printf("%d(%d)\n",w[i-1], strlen(htable[i]));
100 }
101 
102 int main()
103 {
104     int w[100], n, i;
105     scanf("%d", &n);
106     for(i=0;i<n;i++)
107         scanf("%d", &w[i]);
108     HuffmanTree htree;
109     HuffmanCode htable;
110     CreateHuffmanTree(htree, w, n);
111     HuffmanCoding(htree, htable, n);
112     PrintHuffmanCode(htable,w, n);
113     return 0;
114 }
View Code

 

5678: 数据结构实验:哈夫曼树和编码

标签:man   def   包含   ott   结构   打印   using   weight   nbsp   

原文地址:https://www.cnblogs.com/qq-1585047819/p/10841113.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!