zoukankan      html  css  js  c++  java
  • 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;
    }

    运行截图:

  • 相关阅读:
    获取计算机名称
    imagelist用法
    cxgrid的ImageComboBox属性学习
    MlskincolorButton使用方法
    delphi实现窗体组建随窗体大小改变而改变
    判断路径下文件是否存在
    Delphi 按Esc快捷键退出程序的简单方法
    pagecontrol
    LinkedList源码解析
    ArrayList源码分析
  • 原文地址:https://www.cnblogs.com/lzjtdxfxl/p/5372842.html
Copyright © 2011-2022 走看看