Huffman树的编码译码

上个学期做的课程设计,关于Huffman树的编码译码。

要求:

输入Huffman树各个叶结点的字符和权值,建立Huffman树并执行编码操作

输入一行仅由01组成的电文字符串,根据建立的Huffman树进行译码操作,程序最后输出译码后的结果

Huffman.h定义了树的结点信息,各种操作。GCC编译通过。

  1 #ifndef HUFFMAN_H_INCLUDED
  2 #define HUFFMAN_H_INCLUDED
  3 #include <iostream>
  4 #include <stdlib.h>
  5 #include <string>
  6
  7 #define leafNumber 20
  8 #define totalNumber 39
  9 #define maxValue 100
 10 using namespace std;
 11
 12 //权值类型, 这里定义为int
 13 typedef int WType;
 14
 15 //树的结点类型, 这里定义为char, 表示字符
 16 typedef char TElemType;
 17
 18 //Huffman树结点信息定义
 19 typedef struct HuffmanNode{
 20     TElemType data;
 21     WType weight;
 22     int left_child;
 23     int right_child;
 24     int parent;
 25     string code;    //每个结点的编码, 定义为 string 类
 26 };
 27
 28 //Huffman树结构定义
 29 typedef struct HuffmanTree{
 30     HuffmanNode elem[totalNumber];
 31     int currentNumber;
 32 };
 33
 34 /*
 35 *构建Huffman树
 36 */
 37 void createHuffmanTree( HuffmanTree &HT, WType w[], int n ) {
 38     int i, j, p1, p2, min1, min2;
 39     for( i = 0; i < n; i++ ) HT.elem[i].weight = w[i];
 40     for( i = 0; i < 2 * n - 1; i++ )
 41         HT.elem[i].parent = HT.elem[i].left_child = HT.elem[i].right_child = -1;
 42     for( i = n; i < 2 * n - 1; i++ ) {
 43         min1 = min2 = maxValue;
 44         for( j = 0; j < i; j++ ) {
 45             if( HT.elem[j].parent == -1 )
 46                 if( HT.elem[j].weight < min1 ) {
 47                     p2 = p1;
 48                     min2 = min1;
 49                     p1 = j;
 50                     min1 = HT.elem[j].weight;
 51                 }
 52                 else if( HT.elem[j].weight < min2 ) {
 53                     p2 = j;
 54                     min2 = HT.elem[j].weight;
 55                 }
 56         }
 57         HT.elem[i].left_child = p1;
 58         HT.elem[i].right_child = p2;
 59         HT.elem[i].weight = HT.elem[p1].weight + HT.elem[p2].weight;
 60         HT.elem[p1].parent = HT.elem[p2].parent = i;
 61     }
 62     HT.currentNumber = 2 * n - 1;
 63 }
 64
 65 /*
 66 *对Huffman树每个结点进行编码
 67 */
 68 void Coding( HuffmanTree &HT, int n ) {
 69
 70     //当前节点下标
 71             int current = 0;
 72             //父节点下标
 73             int parent = 0;
 74     for( int i = 2 * n - 2 ; i >= 0; i-- ) {
 75
 76         current = i;
 77         parent = HT.elem[current].parent;
 78         /*
 79         if( parent == -1 ) HT.elem[current].code[0] = ‘0‘;
 80         else {
 81             if( HT.elem[parent].left_child == current ) {
 82                 strcat( HT.elem[current].code, HT.elem[parent].code );
 83                 strcat( HT.elem[current].code, "0" );
 84             }
 85             if( HT.elem[parent].right_child == current ) {
 86                 strcat( HT.elem[current].code, HT.elem[parent].code );
 87                 strcat( HT.elem[current].code, "1" );
 88             }
 89         }
 90         */
 91
 92
 93         while (parent != -1)
 94                 {
 95                     if (HT.elem[parent].left_child == current) HT.elem[i].code += "0";
 96                     else HT.elem[i].code += "1";
 97
 98                     current = parent;
 99                     parent = HT.elem[current].parent;
100                 }
101
102         //HT.elem[current].code += "0";
103         reverse( HT.elem[i].code.begin(), HT.elem[i].code.end() );
104
105     }
106
107 }
108
109 /*
110 *译码
111 */
112 void decode( HuffmanTree &HT, int n ) {
113     cout << "输入电文: ";
114     char ch[100];
115     gets( ch );
116
117     int i = 0;
118     int parent;
119     int root = 2 * n - 2;
120     int index = root;
121     int count = 0;
122     int len = strlen( ch );
123     while( ch[i] != ‘#‘ ) {
124         if( ch[i] == ‘0‘ ) {
125             index = HT.elem[index].left_child;
126             //cout << "经过0" << endl;
127             //cout << index << endl;
128             //count++;
129         }
130         else if( ch[i] == ‘1‘ ) {
131             index = HT.elem[index].right_child;
132             //cout << "经过1" << endl;
133             //cout << index << endl;
134             //count++;
135         }
136         if( HT.elem[index].left_child == -1 && HT.elem[index].right_child == -1 ) {
137             cout << HT.elem[index].data;
138             index = root;
139             //i += count;
140             //count = 0;
141             //cout << index << endl;
142         }
143         i++;
144     }
145 }
146 /*
147 *遍历
148 */
149 void PreOrder( HuffmanTree &HT, int n ) {
150     for( int i = 0; i < n; i++ ) {
151         cout << "字符: " << HT.elem[i].data << ", " << "权值: " << HT.elem[i].weight << "  Huffman编码: " << HT.elem[i].code << endl;
152     }
153 };
154
155
156 #endif // HUFFMAN_H_INCLUDED
#include "Huffman.h"
int main() {
    HuffmanTree HT;
    HT.elem[0].data = ‘A‘;
    HT.elem[1].data = ‘B‘;
    HT.elem[2].data = ‘C‘;
    HT.elem[3].data = ‘D‘;
    HT.elem[4].data = ‘E‘;
    WType weight[] = { 7, 5, 2, 4, 6 };
    //WType weight[] = { 5,7,2,13 };
    createHuffmanTree( HT, weight, 5 );
    Coding( HT, 5 );
    PreOrder( HT, 5 );

    cout << endl << endl;
    for( int i = 0; i < 9; i++ )
        cout << "Node " << i << " Code: " << HT.elem[i].code << endl;

    cout << endl << endl;
    for( int i = 0; i < 9; i++ ) {
        cout << "Node " << i << ": " << "weight = " << HT.elem[i].weight << ", parent = " << HT.elem[i].parent << ", left_child = " << HT.elem[i].left_child
                << ", right_child = " << HT.elem[i].right_child << endl;
    }
    decode( HT, 5 );
    return 0;
}

运行截图:

时间: 2024-10-14 09:59:31

Huffman树的编码译码的相关文章

数据结构复习之利用Huffman树进行编码和译码

//编码#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<fstream> #include<map> using namespace std; typedef struct HuffmanNode{ int w;//节点的权值

Huffman树与编码

带权路径最小的二叉树称为最优二叉树或Huffman(哈夫曼树). Huffman树的构造 将节点的权值存入数组中,由数组开始构造Huffman树.初始化指针数组,指针指向含有权值的孤立节点. b = malloc(n*sizeof(BTreeNode)); for (i = 0; i < n; i++) { b[i] = malloc(sizeof(BTreeNode)); b[i]->data = a[i]; b[i]->left = NULL; b[i]->right = NU

【数据结构】哈夫曼树实现编码译码

根据一段字符串中字符的个数 作为该字符的权值生成哈夫曼树. 然后根据生成的哈夫曼编码,对任意字符串实现编码,对任意二进制串实现译码. 程序运行结果: 1.程序主界面: 2.根据字符串 创建哈夫曼树及编码: 3.生成的编码表如下: 4.根据生成的哈夫曼编码对字符串编码: 5.生成的编码保存在文件中: 6.对二进制串译码: 结果: 代码: 哈夫曼树的生成和编码的常见,以及编码和译码函数 //_HuffmanTree_H #ifndef _HuffmanTree_H #define _HuffmanT

哈夫曼树与编码译码实现

一.哈弗曼树的基本概念. 哈夫曼树,又称最优树,是一类带权路径长度最短的树.下面有几个概念: (1)路径. 树中一个结点到另一个结点之间的分支构成这两个结点之间的路径. (2)路径长度. 路径上的分枝数目. (3)树的路径长度. 从树根到每一个结点的路径长度之和. (4)结点的带权路径长度. 从该结点到树根之间的路径长度与结点上权的乘积. (5)树的带权路径长度. 树中所有叶子节点的带权路径长度之和.通常记作: 带权路径长度WPL最小的二叉树叫做最优二叉树或哈夫曼树. 二.构造哈夫曼树. 采用哈

Huffman树及其编码(STL array实现)

这篇随笔主要是Huffman编码,构建哈夫曼树有各种各样的实现方法,如优先队列,数组构成的树等,但本质都是堆. 这里我用数组来存储数据,以堆的思想来构建一个哈弗曼树,并存入vector中,进而实现哈夫曼编码 步骤: 1生成哈夫曼树  (取最小权值树和次小权值树生成新树,排列后重新取树,不断重复)    2编码   (遵循左零右一的原则)           3解码(是编码的逆向,本文还未实现,日后有机会补充) data.txt  测试数据: 51 2 3 4 5abcde 结果: 下面贴代码:

Huffman树费用

问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, -, pn-1},用这列数构造Huffman树的过程如下: 1. 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中.这个过程的费用记为pa + pb. 2. 重复步骤1,直到{pi}中只剩下一个数. 在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用. 本题任务:对于给定的一个数列

Huffman树及其编解码

Huffman树--编解码 介绍: ??Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于数据压缩或者解压缩,和对字符的编解码. ??可是Huffman树的优点在哪? ??1.就在于它对出现次数大的字符(即权值大的字符)的编码比出现少的字符编码短,也就是说出现次数越多,编码越短,保证了对数据的压缩. ??2.保证编的码不会出现互相涵括,也就是不会出现二义性,比如a的编码是00100,b的

哈夫曼(Huffman)树与哈夫曼编码

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4289610.html 哈夫曼树又称最优二叉树,是一种带权路径长最短的树.树的路径长度是从树根到每一个叶子之间的路径长度之和.节点的带树路径长度为从该节点到树根之间的路径长度与该节点权(比如字符在某串中的使用频率)的乘积. 比如有一串字符串如

哈夫曼(Huffman)树和哈夫曼编码

一.哈夫曼(Huffman)树和哈夫曼编码 1.哈夫曼树(Huffman)又称最优二叉树,是一类带权路径长度最短的树, 常用于信息检测. 定义: 结点间的路径长度:树中一个结点到另一个结点之间分支数目称为这对结点之间的路径长度. 树的路径长度:树的根结点到树中每一结点的路径长度之和. 带权路径长度:从根结点到某结点的路径长度与该结点上权的乘积. 树的带权路径长度:树中所有叶子结点的带权路径长度之和记为WPL. 例如: 对图(a): WPL =9×2+5×2+2×2+3×2=38 对图(b): W