哈夫曼编码

  1111110
, 1001
. 11010
A 1110  
B 110110 
C 11110
D 01001
E 000
F 010101
G 111110
H 00110
I 1010
J 1101110001
K 1101111
L 0010
M 00111
N 0110
O 1000
P 01000
Q 1101110000
R 1011
S 1100
T 0111
U 01011
V 11011101
W 1111111
X 1101110011
Y 010100
Z 1101110010
O(n+nlgn)的求最小的两个数
//#include"stdafx.h"
#include <cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define  maxn 29
const char d[29] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',',','.',' ' };   /*明文字符*///空格32 ,44 48 A65
const double WEIGHT[29] = { 8.4966,2.072,4.5388,3.3844,11.16,1.8121,2.4705,3.0034,7.5448,0.1965,1.1016,5.4893,3.0129,6.6544,7.1635,3.1671,0.1962,7.5809,7.5809,6.9509,3.6308,1.0074,1.2899,0.2902,1.7779,0.2722,7.241,4.021,1.231 };//使用频率
string s;
string s1;
class code
{
public :
    char A;//字符
    char Hc[30];//编码
};
code Code[29];
class HuffTree
{
public:
    double weight;
    int x;
    char A;
    int parent;
    int lchild, rchild;
};
class HuffMan
{

public:
    HuffMan() { Front = 0;last = 0;index = 0;M = 2 * maxn - 1;n = maxn; }
    void init();
    void creatHuffTree();
    void minHuffTree();
    void Decode(char []);
    void Incode();
private:
    HuffTree Arr[2 * maxn - 1];//n个叶子节点,n-1个非叶子节点
    HuffTree Queue[20];
    int Front, last;
    int index;
    int M,n;
};
void HuffMan::init()
{
    for (int i = 0;i < n;i++)
    {
    Arr[i].A = d[i];
    Arr[i].weight=WEIGHT[i];
    Arr[i].rchild = Arr[i].lchild = Arr[i].parent = 0;
    }


}
bool cmp(HuffTree &a, HuffTree &b)
{
    return a.weight<b.weight;
}
void HuffMan::minHuffTree()
{
    int i, k = 0;
    int min1, min2, min_index1, min_index2;
    if (index == 0) { HuffTree t;
    min_index1 = 0;min_index2 = 1; min1 = Arr[0].weight; min2 = Arr[1].weight;
    t.weight = Arr[0].weight + Arr[1].weight;
    t.x = --M;Arr[M].weight = t.weight;Arr[M].lchild = min_index1;Arr[M].rchild = min_index2;Arr[min_index2].parent=Arr[min_index1].parent = M;
    Arr[M].x = M;
    Queue[Front] = t;index = 2; return; }
    for (i = index;i<n&&k<1;i++)//第i次最小的两个数
    {
        if (Queue[Front].weight<Arr[i].weight && last >= Front)
        {
            min1 = Queue[Front].weight;
            min_index1 = Queue[Front++].x;
            if (Queue[Front].weight < Arr[i].weight && last >= Front) {
                min_index2 = Queue[Front].x; min2 = Queue[Front].weight;
                if (Queue[Front].weight + min1>Arr[n - 1].weight)
                {
                    Arr[n++].weight = Queue[Front++].weight + min1;

                    Arr[n - 1].x = n - 1;
                    Arr[n - 1].lchild = min_index1; Arr[min_index1].parent = n - 1;
                    Arr[n - 1].rchild = min_index2; Arr[min_index2].parent = n - 1;
                }
                else {
                    Queue[++last].weight = Queue[Front++].weight + min1;Queue[last].x = --M;Arr[M].weight = Queue[last].weight;
                    Arr[M].lchild = min_index1;Arr[min_index1].parent = M;
                    Arr[M].rchild = min_index2;Arr[min_index2].parent = M;
                    Arr[M].x = M;
                }
                k++;i--;
            }
            else {
                min2 = Arr[i].weight;
                min_index2 = i;
                if (Arr[i].weight + min1 > Arr[n - 1].weight)
                {
                    Arr[n++].weight = Arr[i].weight + min1;Arr[n - 1].x = n - 1;
                    Arr[n-1].lchild = min_index1;Arr[min_index1].parent = n-1;
                    Arr[n-1].rchild = min_index2;Arr[min_index2].parent = n-1;
                }
                else {
                    Queue[++last].weight = Arr[i].weight + min1; Queue[last].x = --M;Arr[M].weight = Queue[last].weight;
                    Arr[M].x = M;
                    Arr[M].lchild = min_index1;Arr[min_index1].parent = M;
                    Arr[M].rchild = min_index2;Arr[min_index2].parent = M;
                }
                k++;
            }
        }
        else
        {
            min1 = Arr[i].weight;
            min_index1 = i;
            if (Queue[Front].weight < Arr[i + 1].weight && last >= Front) {
                min2 = Queue[Front].weight;
                min_index2 = Queue[Front].x;
                if (Queue[Front].weight + Arr[i].weight>Arr[n - 1].weight)
                {
                    Arr[n++].weight = Queue[Front++].weight + Arr[i].weight;
                    Arr[n - 1].x = n - 1;
                    Arr[n - 1].lchild = min_index1;Arr[n - 1].rchild = min_index2;
                    Arr[min_index1].parent = Arr[min_index2].parent= n-1;
                }
                else
                {
                    Queue[++last].weight = Queue[Front++].weight + Arr[i].weight;Queue[last].x = --M;
                    Arr[M].weight = Queue[last].weight;
                    Arr[M].x = M;
                    Arr[M].lchild = min_index1;Arr[M].rchild = min_index2;
                    Arr[min_index1].parent = Arr[min_index2].parent = M;
                }
                k++;
            }
            else {
                min2 = Arr[i + 1].weight;
                min_index2 = i + 1;
                if (Arr[i + 1].weight + Arr[i].weight > Arr[n - 1].weight)
                {
                    Arr[n++].weight = Arr[i + 1].weight + Arr[i].weight;
                    Arr[n - 1].x = n - 1;
                    Arr[n - 1].lchild = min_index1;
                    Arr[n - 1].rchild = min_index2;
                    Arr[min_index1].parent = Arr[min_index2].parent = n - 1;
                }
                else
                {
                    Queue[++last].weight = Arr[i + 1].weight + Arr[i].weight;
                    Queue[last].x = --M;
                    Arr[M].weight = Queue[last].weight;
                    Arr[M].x = M;
                    Arr[M].lchild = min_index1;
                    Arr[M].rchild = min_index2;
                    Arr[min_index1].parent = Arr[min_index2].parent = M;
                }
                i++;k++;
            }
        }
    }
    index = i;
}
void HuffMan::Incode()
{
    char p[50];
    int  q=50;
    for (int i = 0;i < maxn;i++)
    {
        HuffTree j=Arr[i];
        q = 49;
        while(j.parent)
        {
            if (Arr[j.parent].lchild == j.x)
                p[--q] = '0';
            else
                p[--q] = '1';
            j = Arr[j.parent];
        }
        Code[i].A=Arr[i].A;
        strcpy(Code[i].Hc,p+q);
    }

}
bool cmp1(code &a,code &b)
{
    return a.A<b.A;
}
void HuffMan::Decode(char clearText[])
{
sort(Code,Code+29,cmp1);
int  len=strlen(clearText);
for(int i=0;i<len;i++)
{

    if(clearText[i]>=97) s.append(Code[clearText[i]-32-62].Hc);
    else  if(clearText[i]==32) s.append(Code[0].Hc);
    else if(clearText[i]==44) s.append(Code[1].Hc);
    else if(clearText[i]==46) s.append(Code[2].Hc);
    else s.append(Code[clearText[i]-62].Hc);
}
cout<<s<<endl;
int length=s.length();
int root=42;
HuffTree t;
for(int j=0;j<length;)
{
    t=Arr[root];
    while(t.lchild||t.rchild)
    {
    if(s[j++]=='0')
    {
    t=Arr[t.lchild];
    }
    else t=Arr[t.rchild];
    }
    s1.push_back(t.A);
}
cout<<s1<<endl;
}
void HuffMan::creatHuffTree()
{
    init();
    sort(Arr, Arr + n, cmp);
    for (int i = 0;i <maxn;i++) Arr[i].x = i;
    for (int i = 0;i<maxn-1;i++)
        minHuffTree();
}
int main()
{

    char clearText[100];
    // freopen("1.in", "r", stdin);
    //freopen("5.txt", "w", stdout);
    HuffMan *H = new HuffMan();
    H->creatHuffTree();
    H->Incode();
    printf("请输入明文码\n");
    scanf("%s",clearText);
    H->Decode(clearText);
    return 0;
    //fclose(stdin);
    //fclose(stdout);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值