哈夫曼树——————数据结构作业

版权声明:转载请注明出处 https://blog.csdn.net/Hpuer_Random/article/details/83546658

实现一个哈夫曼编码系统,系统包括以下功能:

  • 字符信息统计:读取待编码的源文件SourceFile.txt,统计出现的字符及其频率。
  • 建立哈夫曼树:根据统计结果建立哈夫曼树。
  • 建立哈夫曼码表:利用得到的哈夫曼树,将各字符对应的编码表保存在文件Code.txt中。
  • 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile.txt。
SourceFile.txt 的文件内容为:

要对下边的字符进行哈夫曼编码处理

AAAAABBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCDDDDDDDDEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFGGGHHHHHHHHHHH
出现的字符及其频率
A:5
B:25
C:7
D:8
E:14
F:21
G:3
H:11
哈夫曼树
 i   weight  parent  lchild  rchild
 1     5       10        0        0
 2    25       14        0        0
 3     7        9        0        0
 4     8       10        0        0
 5    14       13        0        0
 6    21       12        0        0
 7     3        9        0        0
 8    11       12        0        0
 9    10       11        3        7
10    13       11        4        1
11    23       13       10        9
12    32       14        6        8
13    37       15       11        5
14    57       15       12        2
15    94        0       14       13
各字符对应的编码表 即文件Code.txt
 i  Char   Code
 1   A     0110
 2   B     10
 3   C     0101
 4   D     0111
 5   E     00
 6   F     111
 7   G     0100
 8   H     110
得到的文件ResultFile.txt内容为
01100110011001100110101010101010101010101010101010101010101010101010100101010101010101010101010101011101110111011101110111011101110000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111010001000100110110110110110110110110110110110

代码如下:

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e3+7;

typedef char **HuffmanCode;
typedef struct{
        int weight;
        int parent, lchild, rchild;
}HTNode,*HuffmanTree;
HuffmanTree HT;
HuffmanCode HC;
int m,s1,s2,start,c,f;
char *cd;
int z[30];
void Select(HuffmanTree HT,int n,int &s1,int &s2)//Select函数
{
        int min1 = 0x3f3f3f3f;
        int min2 = 0x3f3f3f3f;
        for(int i=1;i<=n;i++)
        {
                if(HT[i].parent)       continue;//if this node's parent not equal zero,it not root;

                if(HT[i].weight < min1)
                {
                        min1 = HT[i].weight;
                        s1 = i;
                        continue;
                }
                if(HT[i].weight < min2 && HT[i].weight >= min1)
                {
                        min2 = HT[i].weight;
                        s2 = i;
                }
        }
}

void GreatHuffmanTree(HuffmanTree &HT, int n)//建立哈夫曼树
{
        if(n<=1) return ;
        m = 2*n - 1;
        HT = new HTNode[m+1];
        for(int i=1; i<=m; ++i)
                HT[i].parent = HT[i].lchild = HT[i].rchild = 0;
        for(int i=1; i<=n; ++i)//需要更改
                HT[i].weight=z[i];

        for(int i=n+1; i<=m; ++i)
        {
                Select(HT,i-1,s1,s2);
                HT[s1].parent = i;
                HT[s2].parent = i;
                HT[i].lchild = s1;
                HT[i].rchild = s2;
                HT[i].weight = HT[s1].weight + HT[s2].weight;
        }
}

void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n)
{
        HC = new char*[n+1];
        cd = new char[n];
        cd[n-1] = '\0';
        for(int i=1; i<=n; ++i)
        {
                start = n-1;
                c = i;
                f = HT[i].parent;
                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;
}

int main()
{
//        freopen("in.txt", "r", stdin);//文件要和代码放在同一个文件夹
//        freopen("out.txt", "w", stdout);
        char s[MAXN];
        scanf("%s",s);
        int len = strlen(s);
        memset(z,0,sizeof(z));
        for(int i=0;i<len;i++)//统计字符个数
                z[s[i]-'A'+1]++;
        int cnt=0;
        for(int i=1;i<=26;++i)
                if(z[i])
                        cnt++;
        for(int i=1;i<=26;i++)
                if(z[i])
                printf("%c:%d\n",'A'+i-1,z[i]);

        GreatHuffmanTree(HT,cnt);

        //输出一下看看是否建立好哈夫曼数
        printf("\n i   weight  parent  lchild  rchild \n");
        for(int i=1; i<=m; ++i)
                printf("%2d %5d %8d %8d %8d\n",i,HT[i].weight,HT[i].parent,HT[i].rchild,HT[i].lchild);


        CreatHuffmanCode(HT,HC,cnt);
        printf("\n\nHuffmanCode:\n");
        printf(" i  Char   Code\n\n");
        for(int i=1; i<=cnt; ++i)
                printf("%2d   %c     %s\n",i,i+'A'-1,HC[i]);

        puts("");
        for(int i=0;i<len;i++)
                printf("%s",HC[s[i]-'A'+1]);
        return 0;
}

猜你喜欢

转载自blog.csdn.net/Hpuer_Random/article/details/83546658