1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
   功能Function Description:     赫夫曼编码---正误待验证(调试时候感觉有地方好像出错了)
   开发环境Environment:          DEV C++ 4.9.9.1
   技术特点Technique:
   版本Version:
   作者Author:                   可笑痴狂
   日期Date:                   20120803
   备注Notes:                 
   作用:
        输入大写字母组成的字符串,然后以其出现的次数为权重进行编码
*/
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
 
typedef struct Node
{
    unsigned int weight;
    unsigned int parent,left,right;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
 
void HuffmanCoding(int *w,int n,char *s)
{
    HuffmanTree HT;
    HuffmanCode HC;
    HuffmanTree p;
    int m,i,j,s1,s2,min1,min2,c,f,start;
    if(n<1)
        return;
    m=2*n-1;
    HT=new HTNode[m+1];           //0号单元没用
 
    for(p=HT+1,i=1;i<=n;++i,++p,++w)      //初始化
    {
        p->weight=*w;
        p->parent=0;
        p->left=0;
        p->right=0;
    }
    for(;i<=m;++i,++p)
    {
        p->weight=0;
        p->parent=0;
        p->left=0;
        p->right=0;
    }
    for(i=n+1;i<=m;++i)
    {
        min1=min2=0x7fffffff;
        //在HT[1,2,.....i-1]中选择parent为0且weight值最小的两个结点,其序号分别为s1、s2
        for(j=1;j<i;++j)
        {
            if(HT[j].parent==0&&min1>HT[j].weight)
            {
                min1=HT[j].weight;
                s1=j;
            }
        }
        HT[s1].parent=i;
        for(j=1;j<i;++j)
        {
            if(HT[j].parent==0&&min2>HT[j].weight)
            {
                min2=HT[j].weight;
                s2=j;
            }
        }
        HT[s2].parent=i;
        HT[i].left=s1;
        HT[i].right=s2;
        HT[i].weight=HT[s1].weight+HT[s2].weight;
    }
 
    //从叶子节点到根逆向求每个字符的赫夫曼编码
    HC=new char*[n+1];     //分配n个字符编码的头指针向量
    char* cd=new char[n];            //分配求编码的工作空间
    cd[n-1]='\0';
    for(i=1;i<=n;++i)          //逐个字符求其编码
    {
        start=n-1;         //编码结束符标志
        for(c=i,f=HT[i].parent;f;c=f,f=HT[f].parent) //从叶子到根逆向求编码
            if(HT[f].left==c)
                cd[--start]='0';
            else
                cd[--start]='1';
        HC[i]=new char[n-start];
        strcpy(HC[i],&cd[start]);
    }
    delete cd;
    for(i=0;i<n;++i)       //输出编码
        cout<<s[i]<<": "<<HC[i+1]<<endl;
}
 
int main()
{
    char s[1000];
    int i,j;
    int weight[27];
    /*
    HuffmanTree HT;
    HuffmanCode HC;
    */
    cout<<"请输入字符串(大写字母):"<<endl;
    while(cin>>s)
    {
        memset(weight,0,sizeof(weight));
        int len=strlen(s);
        for(i=0;i<len;++i)
            ++weight[s[i]-'A'];
        for(i=0,j=0;i<26;++i)    //去掉没有出现过的字母,将字母和权值都压缩存储到原来的空间中
            if(weight[i])
            {
                s[j]=i+'A';
                weight[j++]=weight[i];
            }
        cout<<"赫夫曼编码为:"<<endl;
        HuffmanCoding(weight,j,s);
        cout<<"请输入字符串(大写字母):"<<endl;
    }
    return 0;
}

 

posted on   可笑痴狂  阅读(404)  评论(0编辑  收藏  举报
努力加载评论中...

点击右上角即可分享
微信分享提示