南京航空航天大学《信息论与编码理论》报告

这篇博客介绍了南京航空航天大学《信息论与编码理论》的实验内容,包括赫夫曼编码的设计与实现,以及循环冗余校验码CRC的构建。通过构建赫夫曼树来生成前缀编码,并详细阐述了CRC码的生成原理和校验过程,用于确保数据传输的可靠性。
摘要由CSDN通过智能技术生成

作者:shmily

目录

实验内容

赫夫曼编码的设计与实现

赫夫曼树:假设有n个权值 {W1,W2,…,Wn},试构造一颗有n个叶子结点的二叉树,每个叶子结点带权为Wi,则其中带权路径长度WPL最小的二叉树称为。

例如下图:有3棵二叉树,都有4个叶子结点a,b,c,d,分别带权7,5,2,4,它们的带权路径长度分别为:

(a)WPL = 72 + 52 + 22 + 42 = 36

(b)WPL = 73 + 53 + 21 + 42 = 46

©WPL = 71 + 52 + 23 + 43 = 35

其中,©树的WPL最小,它便是赫夫曼树,即其带权路径长度在所有带权为7、5、2、4的4个叶子结点的二叉树中居最小。

构造赫夫曼数可以利用赫夫曼最早给出的一个带有一般规律的算法,即赫夫曼算法。步骤如下:

(1)根据给定的n个权值 {W1,W2,…, Wn} 构成n棵二叉树的集合 F={T1,T2,…,Tn},其中每棵二叉树Ti中只有一个带权为Wi的根结点,其左右子树均为空;

(2)在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左右子树上根结点的权值之和;

(3)在F中删除这两棵树,同事将新得到的二叉树加入F中;

(4)重复(2)和(3),直到F只含一棵树为止。这棵树便是赫夫曼树。

例如下图展示了赫夫曼树的构造过程:

赫夫曼编码是赫夫曼树的应用,通常采用前缀编码,使得解码时不会产生混淆。具体方法为;从叶子出发走一条从叶子到根的路径,如上图字符C所在的叶子到根结点的路径为字符串011,再将所得的字符串反转得到110,便是该字符C的编码。继续分析上例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcWPmNLr-1585656751344)(C:\Users\lenovo\Desktop\3.PNG)]

赫夫曼译码是编码的逆向工程,具体做法为:从根出发走一条从根到叶子的路径,如根据字符C的编码110,从根出发,按字符’0’或’1’确定找左孩子或右孩子,直至叶子结点,便求得该编码字符串对应的字符。

源代码:

#include <vector>
#include <iostream>
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
//haffman 树的结构
typedef struct
{
   
    //叶子结点权值
    unsigned int weight;
    //指向双亲,和孩子结点的指针
    unsigned int parent;
    unsigned int lChild;
    unsigned int rChild;
} Node, *HuffmanTree;
//动态分配数组,存储哈夫曼编码
typedef char *HuffmanCode;
//选择两个parent为0,且weight最小的结点s1和s2的方法实现
//n 为叶子结点的总数,s1和 s2两个指针参数指向要选取出来的两个权值最小的结点
void select(HuffmanTree *huffmanTree, int n, int *s1, int *s2)
{
   
    //标记 i
    int i = 0;
    //记录最小权值
    int min;
    //遍历全部结点,找出单节点
    for(i = 1; i <= n; i++)
    {
   
        //如果此结点的没有父节点,那么把结点号赋值给 min,跳出循环
        if((*huffmanTree)[i].parent == 0)
        {
   
            min = i;
            break;
        }
    }
    //继续遍历全部结点,找出权值最小的单节点
    for(i = 1; i <= n; i++)
    {
   
        //如果此结点的父亲为空,则进入 if
        if((*huffmanTree)[i].parent == 0)
        {
   
            //如果此结点的权值比 min 结点的权值小,那么更新 min 结点,否则就是最开始的 min
            if((*huffmanTree)[i].weight < (*huffmanTree)[min].weight)
            {
   
                min = i;
            }
        }
    }
    //找到了最小权值的结点,s1指向
    *s1 = min;
    //遍历全部结点
    for(i = 1; i <= n; i++)
    {
   
        //找出下一个单节点,且没有被 s1指向,那么i 赋值给 min,跳出循环
        if
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值