哈夫曼编码译码系统(c/c++)

哈夫曼编码译码系统的实现,主要包含三部分:

1、创建哈夫曼树

2、编码函数

3、译码函数

编写代码时为了方便,在这里混用了c++的输入输出流。主体用c语言实现。

下面时代码部分:

1、头文件,以及储存结构:

#include<stdio.h>
#include<iostream>
using namespace std;
#define MAX 2000
typedef char ElemType;
typedef struct{
ElemType data;
int w;
int parent,lchild,rchild;
}HFMTNode;

2、哈夫曼树的创建,Ht储存全部节点的权值,n代表叶子节点数量。

void menu(HFMTNode Ht [],int n);//原型声明
void CreatHFMTree(HFMTNode Ht[],int n)//创建哈夫曼树
{
    int i,j,k,lmin,rmin;
    int min1,min2,m1;
    for(i=1;i<2*n;i++)
    {
        Ht[i].parent=Ht[i].lchild=Ht[i].rchild=-1;
    }
    for(i=n+1;i<2*n;i++)
    {
        min1=min2=MAX;
        lmin=rmin=-1;
        for(k=1;k<i;k++)
        {
            if(Ht[k].parent==-1)//只在尚未构造的二叉树节点中运行
            {
                if(Ht[k].w<min1)
                {
                    min2=min1;
                    rmin=lmin;
                    min1=Ht[k].w;
                    lmin=k;
                }
                else
                 {
                    if(Ht[k].w<min2)
                    {
                        min2=Ht[k].w;
                        rmin=k;
                    }
                }
            }
            else{
                if(Ht[k].w<min2&&k>m1)//与创建好的二叉树节点比较,选取w小的一个
                {
                    min2=Ht[k].w;
                    rmin=k;
                    m1=k;
                }
            }
        }
        Ht[lmin].parent=i;//对选择出的结点进行连接
        Ht[rmin].parent=i;
        Ht[i].w=Ht[lmin].w+Ht[rmin].w;
        Ht[i].lchild=lmin;
        Ht[i].rchild=rmin;
    }
    printf("HFMTree have been created\n");
 } 

3、编码译码函数、主函数:

 void encoding(HFMTNode Ht [],int n)//编码
 {
     int k;
     fflush(stdin);
     printf("Please input what you want to encode with the ending of‘#‘ :\n");
     char ch;
     ch=getchar();                      //读取字符
     while (ch!=‘#‘)
     {
         for(k=1;k<=n;k++)
         {
             if(Ht[k].data==ch)
             {
                 break;
             }
         }                           //找到字符位置
         HFMTNode temp1,temp=Ht[k];
         int flag=0;
         int a[n];
         while(temp.w!=Ht[2*n-1].w)
         {
             temp1=temp;
             temp=Ht[temp.parent];
             if(Ht[temp.lchild].w==temp1.w )
             {
                 a[flag]=0;
                 flag++;
             }
             else if(Ht[temp.rchild].w==temp1.w )
             {
                 a[flag]=1;
                 flag++;
             }
          }                               //用数组记录路径
          for(int f=flag-1;f>=0;f--)
          {
              printf("%d",a[f]);
          }                                //编码输出
         ch=getchar();
     }
     printf("\nencoding have finished\n");
    system("pause");
    system("cls");
    menu(Ht,n);
 }
 void decoding(HFMTNode Ht [],int n)//译码
 {
     int k=2*n-1;
     fflush(stdin);
     printf("Please input what you want to decode with the ending of‘#‘ :\n");
     char ch;
     ch=getchar();                      //依次读取01字符
     HFMTNode temp=Ht[2*n-1];
     while (ch!=‘#‘)
    {
        if(ch==‘1‘)
        {
            if(temp.rchild==-1)
            {
                printf("%c",temp.data);           //根据01向左右寻找,到达叶子节点时输出
                temp=Ht[2*n-1];
                continue;
            }
            else
            {
                temp=Ht[temp.rchild ];
                ch=getchar();
            }
        }
        else if(ch==‘0‘)
        {
            if(temp.lchild==-1)
            {
                printf("%c",temp.data);
                temp=Ht[2*n-1];
                continue;
            }
            else
            {
                temp=Ht[temp.lchild ];
                ch=getchar();
            }
        }
    }
    printf("%c",temp.data);                    //输出要译码的最后一个字符
    printf("\ndecoding have finished\n");
    system("pause");
    system("cls");
    menu(Ht,n);
 }
 void menu(HFMTNode Ht [],int n)
 {
     int j;
     printf("Input your choice:\n");
     printf("1.encoding      2.decoding      0.exit\n");
     cin>>j;
     switch (j)
     {
         case 1:encoding(Ht,n);break;
         case 2:decoding(Ht,n);break;
         case 0:break;
     }
 }
 int main()
 {
     printf("Please input the amount of the node:\n");
     int i;
     scanf("%d",&i);
     HFMTNode Ht[2*i];//储存各个节点的数据
     for(int k=1;k<=i;k++)
     {
         printf("Ht[%d]:Please input data :",k);
         cin>>Ht[k].data;
         printf("Ht[%d]:Please input w :",k);
         cin>>Ht[k].w;
     }
     CreatHFMTree(Ht,i);
     menu(Ht,i);
     return 0;
 }

上面代码放在一起即可直接运行,本人水平有限,如有错误,欢迎大神指正。

原文地址:https://www.cnblogs.com/a1969503125/p/10970017.html

时间: 2024-10-13 16:17:49

哈夫曼编码译码系统(c/c++)的相关文章

基于python的二元霍夫曼编码译码详细设计

一.设计题目 对一幅BMP格式的灰度图像(个人证件照片)进行二元霍夫曼编码和译码 二.算法设计 (1)二元霍夫曼编码: ①:图像灰度处理: 利用python的PIL自带的灰度图像转换函数,首先将彩色图片转为灰度的bmp图像,此时每个像素点可以用单个像素点来表示. ②:二元霍夫曼编码: 程序流程图: 详细设计: 统计像素点频率,首先通过python自带的PIL库的图像像素点读取函数read()获取灰度图像的所有像素点,通过循环遍历每个像素点,将每个出现的像素点值以及其次数以键值对的形式放入到pyt

数据结构课程设计-哈夫曼编码译码

//******************************************** //程序功能:哈夫曼编码及译码 // //日期:2014年11月18 // //******************************************** #include<stdio.h> #include<stdlib.h> #include<string.h> #include <windows.h> #define MAX 128 //叶子节点

哈弗曼编码译码系统

/**********************************************************************                                        * 学校:黄淮学院                                                         * 院系:信息工程学院                                                     * 年级专业:网络

哈夫曼编码和译码

构建哈夫曼原理:(每个元素都是叶子结点,N 个元素共有 2N-1 个结点) 有 N 个带权值的结点,将其按以下方法构建:①②③ ①选取 N 个结点集合中最小的两个权值结点构造成一个新的二叉树,且设置新结点的权值为左右孩子权值之和 ②将以上选取的两个最小权值结点从原集合中删除,向集合中加入 这两个结点的跟,即 1 中创建的新结点,此时集合 元素为 N = N - 2 + 1;  ③重复 ① ② 直到只剩下一个结点,该结点就是构建的二叉树的根 哈夫曼编码原理: 在哈夫曼树中,凡是左分支,即左孩子的全

哈弗曼树的构建,哈夫曼编码、译码

哈夫曼树的基本概念 哈夫曼树(Huffman Tree),又叫最优二叉树,指的是对于一组具有确定权值的叶子结点的具有最小带权路径长度的二叉树. (1)路劲(Path):从树中的一个结点到另一个结点之间的分支构成两个结点间的路径. (2)路径长度(Path Length):路径上的分支树. (3)树的路径长度(Path Length of Tree):从树的根结点到每个结点的路径长度之和.在结点数目相同的二叉树中,完全二叉树的路径长度最短. (4)结点的权(Weight of  Node):在一些

二叉树的基本操作及哈夫曼编码系统的实现

实验环境:win10,VC++ 6.0  使用语言:C/C++ 实验内容一:编写程序,完成二叉树的先序创建.先序遍历.中序遍历和后序遍历等操作 Binary.h 1 #include<iostream> 2 #include<stdlib.h> 3 #include<stack> 4 #include<queue> 5 using namespace std; 6 7 typedef char ElemType; 8 9 typedef struct BiT

数据结构:哈夫曼编码(php版)

演示网址:http://huffman.sinaapp.com/ 源文件下载地址:http://xiaocao.u.qiniudn.com/work/huffman-2013-12-19.zip 概述下: 哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩.     简单的,就是靠权值排序,然后,转码,最优保存. 实现功能: 保存译码:在服务器端保存源

哈夫曼编码课程设计+最小优先对列建树。

问题描述 利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本.这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原).对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统.试为这样的信息收发站编写一个赫夫曼码的编/译码系统. 基本要求 一个完整的系统应具有以下功能: (1) I:初始化(Initialization).从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中. (

哈夫曼编码

   1.问题描述 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法.其压缩率通常在20%-90%之间.哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式.一个包含100,000个字符的文件,各字符出现频率不同,如下表所示. 有多种方式表示文件中的信息,若用0,1码表示字符的方法,即每个字符用唯一的一个0,1串表示.若采用定长编码表示,则需要3位表示一个字符,整个文件编码需要300,000位:若采用变长编码表示,给频率高的字符较短的编码:频率低的字符较长的