精华内容
下载资源
问答
  • 哈夫曼树与哈夫曼编码 建立哈夫曼树并计算哈夫曼编码
  • #include <stdlib.h>/*哈夫曼树建立哈夫曼编码算法的实现*/ #include typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/ typedef struct { unsigned int weight ; /* 用来存放各个结点的权值*/...

     

    展开全文
  • // 哈夫曼树.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #define MAX 20 using namespace std; typedef char valType; typedef double wghType; struct HFMnode ...
    
    

    // 哈夫曼树.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include<iostream>
    #define MAX 20
    using namespace std;
    typedef char valType;
    typedef double wghType;

    struct HFMnode
    {
    valType data;
    wghType weight;
    int parent;
    int lchild;
    int rchild;
    };
    //每个节点的编码
    //code存储编码
    //start存储编码是从code数组的第几个开始
    //在编码过程中从叶子节点向根节点逆推
    struct HFMcode
    {
    char code[MAX];
    int start;
    };
    //建立哈夫曼树
    void createHFMtree(HFMnode *node,int n)
    {
    int i;
    //m1,m2为当前还没用到的节点中权值最小和次小的权值
    int m1,m2;
    //l,r为每次构建一个父节点其左右儿子节点的序号
    int l,r;
    for(i=n+1;i<=2*n-1;i++)
    {
    m1=m2=32767;
    l=r=0;
    int k;
    for(k=1;k<=i-1;k++)
    if(node[k].parent==0)
    {
    if(node[k].weight<m1)
    {
    m2 = m1;
    r = l;
    m1 = node[k].weight;
    l = k;
    }
    else if(node[k].weight<m2)
    {
    m2 = node[k].weight;
    r = k;
    }
    }
    node[i].weight = node[l].weight + node[r].weight;
    node[i].lchild = l;
    node[i].rchild = r;
    node[l].parent = i;
    node[r].parent = i;
    }
    }
    //求每个节点的哈夫曼编码
    void createHFMcode(HFMnode *node, HFMcode *hcode,int n)
    {
    int i;
    for(i=1;i<=n;i++)
    {
    HFMcode d;
    //哈夫曼树最大层数就是元素的个数
    d.start = n;
    int num=i;
    int father = node[num].parent;
    while(father!=0)
    {
    if(node[father].lchild==num)
    d.code[d.start--]='0';
    else
    d.code[d.start--]='1';
    num = father;
    father = node[num].parent;
    }
    hcode[i]=d;
    }
    }
    //打印每个节点的编码
    void printHFMcode(HFMnode * node,HFMcode * hcode,int n)
    {
    int i;
    for(i=1;i<=n;i++)
    {
    cout<<node[i].data<<" :";
    for(int k = hcode[i].start+1; k<=n;k++)
    cout<<hcode[i].code[k];
    cout<<endl;
    }
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    HFMnode node[2*MAX];
    HFMcode hcd[MAX];
    cout<<"请输入案例个数:"<<endl;
    int cases;
    cin >> cases;
    while(cases--)
    {
    cout<<"请输入元素个数:"<<endl;
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++)
    {
    cout<<"输入第"<<i<<"个节点的值:"<<endl;
    cin>>node[i].data;
    cout<<"输入它的权重:"<<endl;
    cin>>node[i].weight;
    }
    for(i=1;i<=2*n-1;i++)
    {
    node[i].parent=node[i].lchild=node[i].rchild=0;
    }
    //建立哈夫曼树
    createHFMtree(node,n);
    //求每个节点的哈夫曼编码
    createHFMcode(node,hcd,n);
    //打印每个节点的编码
    cout<<"输出每个节点的哈夫曼编码:"<<endl;
    printHFMcode(node,hcd,n);
    }
    return 0;
    }

    展开全文
  • 最近完成了数据结构课程设计,被分到的题目是《哈夫曼编码和解码》,现在在这篇博文里分享一下自己的成果。  我在设计时,在网上参考了很多老师和前辈的算法和代码,向他们表示感谢!他们的成果给了我很多启示和...

      最近完成了数据结构课程设计,被分到的题目是《哈夫曼编码和解码》,现在在这篇博文里分享一下自己的成果。

      我在设计时,在网上参考了很多老师和前辈的算法和代码,向他们表示感谢!他们的成果给了我很多启示和帮助。另外,自己的成品中也还有很多不完善的地方,欢迎批评指正。

    课题:哈夫曼编码与解码 C++代码实现

    (1)统计某电文中字符出现的频率(假设电文中只含有大小写英文字母,以及逗号和点号);
    (2)把字符出现的频率作为权值建立哈夫曼树,进行哈夫曼编码,并输出每个字符的编码结果;
    (3)对电文进行哈夫曼编码;
    (4)把电文的哈夫曼编码进行译码,输出对应电文的内容。

      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 #include <malloc.h>
      4 #include <string.h>
      5 #include <ctype.h>
      6 #define MAX 999999 //一个极大值
      7 #define NUM 10
      8 
      9 //存储哈夫曼树每个结点
     10 typedef struct Node {
     11     char ch;
     12     int weight; //权值
     13     int parent;
     14     int lchild,rchild;
     15 }HFNode;
     16 //存储每个字符及其哈夫曼编码
     17 typedef struct {
     18     char ch;
     19     char code[NUM];
     20 }HFCharCode;
     21 
     22 HFNode HT[28*2-1]; //哈夫曼树结构体
     23 HFCharCode HCD[28]; //哈夫曼编码结构体
     24 int LeafNum; //叶子结点数
     25 int NodeNum; //所有结点数
     26 char EnterStr[MAX]; //输入的待编码电文
     27 char EnterCode[MAX]; //输入的待解码密文
     28 char RealStr[MAX]; //密文解码后的电文
     29 int AllWeight[28]; //存储所有28个字符的权值
     30 
     31 void Statistics();
     32 void CreateHFTree();
     33     void SelectMin(int &min1, int &min2);
     34 void CreateHFCode();
     35     void ReverseStr(char *str);
     36 void EncodeStr();
     37 void DecodeHFCode();
     38 
     39 int main() {
     40     printf("****** 哈夫曼编码与解码 ******\n\n");
     41     printf("*** 输入一串字符串 ***\n");
     42     scanf("%s", EnterStr);
     43     getchar();
     44     Statistics();
     45     CreateHFTree();
     46     CreateHFCode();
     47     EncodeStr();
     48     printf("\n*** 输入想解码的内容 ***\n");
     49     scanf("%s", EnterCode);
     50     getchar();
     51     DecodeHFCode();
     52     return 0;
     53 }
     54 
     55 //统计每个字符权值
     56 void Statistics() {
     57     int len = strlen(EnterStr);
     58     for(int i = 0; i <= 27; i++)
     59         AllWeight[i] = 0;
     60     for(int j = 0; j <= len - 1; j++) {
     61         if(isalpha(EnterStr[j])) {
     62             EnterStr[j] = tolower(EnterStr[j]);
     63             AllWeight[EnterStr[j]-'a']++;
     64         }
     65         else if((int)EnterStr[j] == 44)
     66             AllWeight[26]++;
     67         else if((int)EnterStr[j] == 46)
     68             AllWeight[27]++;
     69         else {
     70             printf("\n输入不符合要求!\n\n");
     71             exit(-1);
     72         }
     73     }
     74     int i = 0, j = 0;
     75     for( ; i <= 25; i++) {
     76         if(AllWeight[i] != 0) {
     77                 HT[j].weight  = AllWeight[i];
     78                 HT[j].ch = i+'a';
     79                 j++;
     80         }
     81     }
     82     if(AllWeight[i] != 0) {
     83             HT[j].weight = AllWeight[i];
     84             HT[j].ch = ',';
     85             j++;
     86             i++;
     87     }
     88     if(AllWeight[i] != 0) {
     89             HT[j].weight = AllWeight[i];
     90             HT[j].ch = '.';
     91     }
     92     printf("\n*** 打印每个字符的权值 ***\n");
     93     int n = 0;
     94     for(int i = 0; i <= 27; i++) {
     95         if(AllWeight[i] != 0) {
     96             n++;
     97             if(i <= 25)
     98                 putchar('a'+i);
     99             else if(i == 26)
    100                 printf(",");
    101             else
    102                 printf(".");
    103             printf(": %d\n", AllWeight[i]);
    104         }
    105     }
    106     LeafNum = n;
    107     NodeNum = 2*LeafNum-1;
    108 }
    109 
    110 //构造哈夫曼树
    111 void CreateHFTree() {
    112     int i;
    113     for(i = 0; i <= LeafNum-1; i++) {
    114         HT[i].parent = -1;
    115         HT[i].lchild = -1;
    116         HT[i].rchild = -1;
    117         HT[i].weight = HT[i].weight;
    118     }
    119     for(; i <= NodeNum-1; i++) {
    120         HT[i].parent = -1;
    121         HT[i].lchild = -1;
    122         HT[i].rchild = -1;
    123         HT[i].weight = MAX;
    124     }
    125     int min1, min2;
    126     for(i = LeafNum; i <= NodeNum-1; i++) {
    127         SelectMin(min1, min2);
    128         HT[min1].parent = i;
    129         HT[min2].parent = i;
    130         HT[i].lchild = min1;
    131         HT[i].rchild = min2;
    132         HT[i].weight = HT[min1].weight + HT[min2].weight;
    133     }
    134     // printf("\n*** 打印哈夫曼树 ***\n");
    135     // for(int i = 0; i <= NodeNum-1; i++) {
    136     //     printf("序号:%d 字符:%c 权值:%d 双亲:%d 左孩:%d 右孩:%d\n", i, HT[i].ch, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
    137     // }
    138 }
    139     //找到两个权值最小的二叉树的序号
    140     void SelectMin(int &min1, int &min2) {
    141         int i = 0;
    142         int temp;
    143         int wetmin1, wetmin2;
    144         while(HT[i].parent != -1) 
    145             i++;
    146         wetmin1 = HT[i].weight;
    147         min1 = i;
    148         i++;
    149         while(HT[i].parent != -1) 
    150             i++;
    151         wetmin2 = HT[i].weight;
    152         min2 = i;
    153         i++;
    154         if(wetmin1 > wetmin2) {
    155             temp = wetmin2;
    156             wetmin2 = wetmin1;
    157             wetmin1 = temp;
    158             temp = min2;
    159             min2 = min1;
    160             min1 = temp;
    161         }
    162         for(; i <= NodeNum-1; i++) {
    163             if(HT[i].weight < wetmin1 && HT[i].parent == -1) {
    164                 wetmin2 = wetmin1;
    165                 wetmin1 = HT[i].weight;
    166                 min2 = min1;
    167                 min1 = i;
    168             } else if(HT[i].weight < wetmin2 && HT[i].parent == -1) {
    169                 wetmin2 = HT[i].weight;
    170                 min2 = i;
    171             }
    172         }
    173     }
    174 
    175 //进行哈夫曼编码
    176 void CreateHFCode() {
    177     int i, j, len; 
    178     for(i = 0; i <= LeafNum-1; i++) {  
    179         len = 0;  
    180         j = i;
    181         HCD[i].ch = HT[j].ch;
    182         while(HT[j].parent != -1) {  //不是根节点
    183             if(HT[HT[j].parent].lchild == j) {  //是双亲结点的左孩子
    184                 HCD[i].code[len++] = '0'+0;  //加上字符0
    185             }else  //是右孩子
    186                 HCD[i].code[len++] = '0'+1;  //加上字符1
    187             j = HT[j].parent;  //往上遍历
    188         }
    189         HCD[i].code[len] = '\0'; //字符串末尾 
    190         ReverseStr(HCD[i].code); 
    191     }
    192     printf("\n*** 打印每个字符的编码 ***\n");
    193     for(int i = 0; i <= LeafNum-1; i++)
    194         printf("%c: %s\n", HT[i].ch, HCD[i].code);
    195 }
    196     //将一个字符串反转  
    197     void ReverseStr(char *str) {  
    198         int i, j;  
    199         char c;  
    200         for(i = 0, j = strlen(str)-1; i < j; i++, j--) {  
    201             c = str[i];  
    202             str[i] = str[j];  
    203             str[j] = c;  
    204         }
    205     }
    206 
    207 //哈夫曼编码
    208 void EncodeStr() {
    209     int len = strlen(EnterStr);
    210     printf("\n*** 编码结果 ***\n");
    211     for(int i = 0; i <= len-1; i++) {
    212         for(int j = 0; j <= LeafNum-1; j++) {
    213             if(EnterStr[i] == HCD[j].ch)
    214                 printf("%s", HCD[j].code);
    215         }
    216     }
    217     printf("\n");
    218 }
    219 
    220 //哈夫曼解码
    221 void DecodeHFCode() {
    222     int k = NodeNum-1; //根结点序号, 开始时一定在最后一个
    223     int len = 0, i = 0;  
    224     while(EnterCode[i]) {  
    225         if(EnterCode[i] == '0'+0)  
    226             k = HT[k].lchild;  
    227         else if(EnterCode[i] == '0'+1)  
    228             k = HT[k].rchild;  
    229         else {
    230             printf("\n错误! 密文中仅能含有1和0!\n\n");
    231             exit(-1);
    232         }  
    233         if(HT[k].lchild == -1 && HT[k].rchild == -1) {  
    234             RealStr[len++] = HT[k].ch;
    235             k = NodeNum-1;
    236         }  
    237         i++;  
    238     }
    239     RealStr[len] = '\0';
    240     if(k == NodeNum-1) {     
    241         printf("\n*** 解码结果 ***\n%s\n\n", RealStr);
    242         exit(0);
    243     }
    244     printf("\n错误! 部分密文无法解密!\n\n");
    245     exit(-1);  
    246 }

     

    转载于:https://www.cnblogs.com/deepcho/p/huffman-tree-node-code-decode-encode-cpp.html

    展开全文
  • 为这些字母设计相应的哈夫曼编码!方法:每次在哈夫曼树构造过程中,两个最小数的选择总是最小的在左,而次小的在右。 输入输出样例:1组 #1 样例输入: abcdefg# //#代表结束符 0.31 0.16 0.10 0.08 0.11 0.20...

     

    通信的电文由字符集中的字母构成,每个字母在电文中会有一个出现的频率。为这些字母设计相应的哈夫曼编码!方法:每次在哈夫曼树构造过程中,两个最小数的选择总是最小的在左,而次小的在右。

    输入输出样例:1组

    #1

    • 样例输入:
      abcdefg# //#代表结束符
      0.31
      0.16
      0.10
      0.08
      0.11
      0.20
      0.04 //代表每个字母的出现频率
    • 样例输出:
      a:11
      b:101
      c:010
      d:1001
      e:011
      f:00
      g:1000
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define  max 100
    typedef struct
    {
        float weight;
        char lchild;
        char rchild;
        int parent;
    } HType;
    typedef struct
    {
        char ch;
        int hfm[max];
        int start;
    } HCode;
    void Creat_huffMTree(HType HFMTree[],int n)
    {
        int y1,y2,x1,x2;
        int i,j;
        HCode hc;
        for(i=0; i<2*n-1; i++) //HFMTree初始化
        {
            HFMTree[i].weight=0;
            HFMTree[i].parent=-1;
            HFMTree[i].lchild=-1;
            HFMTree[i].rchild=-1;
        }
        for(i=0; i<n; i++) //输入n个叶子节点的权值
        {
            scanf("%f",&HFMTree[i].weight);
        }
        for(i=0; i<n-1; i++)
        {
            x1=x2=max;
            y1=y2=0;
            for(j=0; j<n+i; j++) //找出根最小和次小权值的两棵树
            {
                if(HFMTree[j].parent==-1&&HFMTree[j].weight<x1)
                {
                    x2=x1;
                    y2=y1;
                    x1=HFMTree[j].weight;
                    y1=j;
                }
                else if(HFMTree[j].parent==-1&&HFMTree[j].weight<x2)
                {
                    x2=HFMTree[j].weight;
                    y2=j;
                }
            }
            HFMTree[y1].parent=n+i;
            HFMTree[y2].parent=n+i;//将找出的两棵树合并成一棵树
            HFMTree[n+i].weight=HFMTree[y1].weight+HFMTree[y2].weight;
            HFMTree[n+i].lchild=y1;
            HFMTree[n+i].lchild=y2;
        }
    }
    void createHFMCode(HType HFMTree[], HCode HFMCode[], int n)
    {
        HCode hc;
        int i, j, r, p;
        for(i = 0; i < n; i++)
        {
            hc.start = max - 1;
            r = i;
            p = HFMTree[r].parent;
            while(p != -1)
            {
                if(HFMTree[p].lchild == r)
                    hc.hfm[hc.start] = 0;
                else
                    hc.hfm[hc.start] = 1;
                hc.start--;
                r = p;
                p = HFMTree[r].parent;
            }
            for(j = hc.start + 1; j < max; j++)
                HFMCode[i].hfm[j] = hc.hfm[j];
            HFMCode[i].start = hc.start + 1;
        }
    }
    int main()
    {
        char arr[max];
        int n,i=0,j;
        HCode hcode[max];
        while(arr[i]!='#')
        {
    
            scanf("%c",&arr[i]);
            hcode[i].ch=arr[i];
            i++;
        }
        n = i;
        HType HFMTree[2*n-1];
        Creat_huffMTree(HFMTree,n);
        createHFMCode(HFMTree,hcode,n);
        for(i=0; i<n; i++)
        {
            printf("%c:",hcode[i].ch);
            for(j= hcode[i].start;j<max;j++)
                printf("%d",hcode[i].hfm[j]);
            printf("\n");
        }
        return 0;
    }
    

     

    展开全文
  • #include #include #include<iomanip>#define MAXSIZE 30 using namespace std;/*哈夫曼编码的存储方式*/ typedef struct Node { char ch; int weight; int parent,Lchirld,Rchirld; }Huff;v
  • 哈夫曼编码

    2019-01-23 21:22:25
    哈夫曼树 哈夫曼树就是一棵带权二叉树、它的WPL是最小的、也就是从根节点到...完成哈夫曼编码首先要先建立哈夫曼树、根据树中节点的路径、计算出对应节点的编码。 下面我写了一个类其中就包含了建立哈夫曼树和完成...
  • 好,现在就来复习一下哈夫曼树的建立过程和哈夫曼编码怎么看,其实很简单,不对,是相当简单~~~~直接用例子来做比较容易理解一点  问:求画出下面数字的哈夫曼树和所有子节点的哈夫曼编码,数字有: 答: ...
  • 哈夫曼树,也称最优二叉树,是数据结构的一个重要内容,实际运用中我们通过哈夫曼编码来大幅度提高无损压缩的比例。 弄清哈夫曼树,我们首先要弄清以下四个概念。 概念1:什么是路径? 在一棵树中,从一个结点到另一...
  • 哈夫曼 编码解码

    2020-11-07 15:28:40
    给定字符串, 建造哈夫曼树,并将字符串转为哈夫曼编码 1. 字符串 2. 字符权值 3. 哈夫曼树建立 4. 字符所对应的哈夫曼编码 5. 字符串编码结果 6. JS源码 : /** * @author 轩 http://wx0725.top * 如果a.val...
  • 给定n个权值作为n的叶子结点,构造一颗二叉树,若带权路径长度达到最小,成这样的二叉树为最有二叉树,也称为哈夫曼树 。哈夫曼树是带全路径长度最短的树,权值较大的结点离根较近。 哈夫曼树的构造: 假设有n个...
  • 文章目录使用哈夫曼编码进行压缩文本文本内容读取文件内容至内存中遍历文本内容,获取每个字符对应出现概率值建立哈夫曼树获取哈夫曼编码将转换后的编码写入新文件检测压缩率利用编码文件进行还原文本完整code ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 529
精华内容 211
关键字:

哈夫曼编码建立