哈夫曼树及应用(实验7--作业)

电文的编码和译码(哈夫曼树的应用) 一、        实验环境 学宝虚拟机,VC6.0二、        实验目的 从键盘接收一串电文字符,输出对应的哈夫曼编码,同时能翻译哈夫曼编码生成的代码串,输出对应的电文字符。三、        实验内容1.用C语言实现二叉树的链式(二叉链表)存储结构;2.实现二叉树的基本操作的有关算法(二叉树的建立、各种遍历等);3.定义二叉树的静态链表结构,并利用这种结构存储哈夫曼树,利用哈夫曼树解决编... 阅读详情

哈夫曼树是一种非常重要的数据结构,在数据压缩等诸多领域有着广泛的应用。本文将详细讲解一段实现哈夫曼树构建、编码以及译码功能的C++代码,帮助大家深入理解哈夫曼树的原理和实现细节。

一、代码整体结构概述

这段C++代码主要实现了以下几个功能模块:

  1. 定义哈夫曼树节点结构体和相关类型别名:通过typedef定义了HTNode结构体来表示哈夫曼树的节点,包含了权值、双亲、左孩子和右孩子的下标信息。同时定义了HuffmanTree作为指向HTNode结构体的指针类型,以及HuffmanCode作为二维字符指针类型用于存储哈夫曼编码。
  2. 查找最小值函数(SelectMin):用于在给定的哈夫曼树节点数组中,找到权值最小和次小且父节点为0的两个节点。这是构建哈夫曼树过程中选择节点合并的关键步骤。
  3. 构建哈夫曼树函数(CreateHuffmanTree):根据输入的叶子节点个数,初始化哈夫曼树节点数组,并通过不断选择权值最小和次小的节点进行合并,逐步构建出完整的哈夫曼树。
  4. 保存哈夫曼编码函数(CreateHuffmanCode):在已经构建好的哈夫曼树基础上,从叶子节点到根节点逆向遍历,为每个叶子节点生成对应的哈夫曼编码,并存储在HuffmanCode类型的二维数组中。
  5. 打印哈夫曼树数组函数(printHaffmamTree):将哈夫曼树节点数组的信息,包括节点索引、权值、父节点、左孩子和右孩子下标等,以清晰的格式打印输出,方便查看哈夫曼树的结构。
  6. 打印哈夫曼编码数组函数(printHaffmanCode):把每个叶子节点对应的哈夫曼编码以及其索引和对应的字符(这里假设按照索引 + 96转换为字符)以表格形式打印出来,展示哈夫曼编码的结果。
  7. 翻译哈夫曼树函数(HuffmanCodeTranslate):实现对输入的二进制码进行译码操作,根据已经构建好的哈夫曼树和编码规则,将二进制码还原为对应的字符序列。

二、关键代码模块详解

(一)哈夫曼树节点结构体及类型别名定义

typedef struct {
    int weight;         //权值
    int parent, lchild, rchild;  //双亲、左右孩子下标
} HTNode, *HuffmanTree;      //动态分配数组存储哈夫曼树

//指针数组,存放每个编码首元素地址
typedef char **HuffmanCode;  //动态分配数组存储哈夫曼编码表

在这里,我们定义了HTNode结构体来描述哈夫曼树的节点特征。每个节点包含了自身的权值(weight),以及指向其双亲(parent)、左孩子(lchild)和右孩子(rchild)的下标信息。通过HuffmanTree和HuffmanCode这两个类型别名,使得后续代码在处理哈夫曼树和哈夫曼编码时更加方便和清晰。

(二)查找最小值函数(SelectMin)

//查找最小值
void SelectMin(HuffmanTree& HT, int k, int& s1, int& s2) {
    //初始化为极大的数来查找最小的两个数
    int min1 = MaxValue;
    int min2 = MaxValue;

    //前k个节点中找
    for(int i = 1; i <= k; i++) {
        if (HT[i].weight < min1 && HT[i].parent == 0) {
            min1 = HT[i].weight;
            s1 = i;
        }
    }
    for(int j = 1; j <= k; j++) {
        if (HT[j].weight < min2 && HT[j].parent == 0 && j!= s1) {
            min2 = HT[j].weight;
            s2 = j;
        }
    }
}

这个函数的目的是在哈夫曼树节点数组HT的前k个节点中,找到权值最小和次小且父节点为0的两个节点。首先,我们将min1和min2初始化为一个极大值(这里通过MaxValue定义)。然后,通过两个嵌套的for循环来实现查找。第一个循环找到权值最小且父节点为0的节点,记录其权值到min1,下标到s1。第二个循环在排除已经找到的s1节点的情况下,找到权值次小且父节点为0的节点,记录其权值到min2,下标到s2。需要注意的是,这里的实现方式虽然能够完成功能,但存在一定的局限性,后续在构建哈夫曼树过程中可能会出现一些逻辑上的小瑕疵(后面会详细讲解)。

(三)构建哈夫曼树函数(CreateHuffmanTree)

//构造哈夫曼树
void CreateHuffmanTree(HuffmanTree& HT, int n) {
    if (n <= 1) return;  //叶子节点数量为1,直接退出函数

    int m = 2 * n - 1;  //HT空间数
    HT = new HTNode[m + 1];  //申请2n空间(0号不用),每个节点都是一个只有根节点的树

    //先初始化
    //所有节点的孩子节点、父母节点都为0
    for(int i = 1; i <= m; i++) {
        HT[i].lchild = 0;
        HT[i].rchild = 0;
        HT[i].parent = 0;
    }

    //再输入每个节点的权值
    //前n个存放叶子节点的权值
    for(int i = 1; i <= n; i++) {
        cout << "请输入第" + i << "个节点的权值:";
        cin >> HT[i].weight;
    }

    //然后根据哈夫曼树的规则进行一系列操作构建哈夫曼树
    //前n个为未被操作的节点,从n + 1个开始构建
    for(int i = n + 1; i <= m; i++) {
        int s1, s2;
        //在HT中的前i - 1个节点中选两个最小且父母节点为0的点
        //因为选出来后会当作HT第i个节点的左右孩子,且插入左右孩子后
        //得到的新节点的parent为0,所以每次从前i - 1个节点中找
        SelectMin(HT, i - 1, s1, s2);
        //选出来最小节点下标s1,次小节点下标s2后
        HT[s1].parent = i;
        HT[s2].parent = i;  //都接在第i个节点下,相当于删除操作
        HT[i].lchild = s1;
        HT[i].rchild = s2;  //选择操作
        //HT[i]为HT[s1],HT[s2]合并后的节点,weight要合并
        HT[i].weight = HT[s1].weight + HT[s2].weight;  //合并操作
    }
}

在这个函数中,我们首先判断输入的叶子节点个数n,如果小于等于1,则直接返回,因为哈夫曼树至少需要两个叶子节点才能构建。然后,我们根据公式m = 2 * n - 1计算出哈夫曼树总共需要的节点数m,并动态分配了相应的内存空间来存储哈夫曼树节点数组HT。接着,对所有节点的孩子节点、父母节点进行初始化设置为0。之后,通过循环输入每个叶子节点的权值。最后,在构建哈夫曼树的核心循环中,每次调用SelectMin函数在前i - 1个节点中选择两个最小且父节点为0的节点,将它们作为新节点i的左右孩子,并更新相关节点的父节点、孩子节点以及新节点的权值等信息,逐步构建出完整的哈夫曼树。

(四)保存哈夫曼编码函数(CreateHuffmanCode)

//保存哈夫曼编码
void CreateHuffmanCode(HuffmanTree& HT, int n, HuffmanCode& HC) {
    // 先为HC分配内存,假设每个编码最长不超过n位
    HC = new char *[n + 1];
    for (int i = 1; i <= n; i++) {
        HC[i] = new char[n + 1];  // 多分配一位用于存储字符串结束符'\0'
    }

    //从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码
    stack<char> S;  //临时栈 用来存放每个根节点的逆向路径后正向输出
    for(int i = 1; i <= n; i++) {  // n个叶子节点对应的哈夫曼编码
        int c = i;  // 当前节点
        and p = HT[i].parent;  //向上查找当前节点的父母节点
        while(p!= 0) {  //当前节点的父母节点还不是根节点时
            if (HT[p].lchild == c) S.push('0');  //左0
            else if (HT[p].rchild == c) S.push('1');  //右1
            c = p;
            p = HT[c].parent;  //向上倒推
        }  //此时S中存放的为第i个节点的逆向路径

        //正向存储在HC[i][…]中
        int j = 0;
        while(!S.empty()) {
            HC[i][j++] = S.top();
            S.pop();
        }
        HC[i][j] = '\0';
    }
}

此函数用于为已经构建好的哈夫曼树生成哈夫曼编码。首先,为HuffmanCode类型的二维数组HC分配内存空间,假设每个编码最长不超过n位(这里n是叶子节点个数),并多分配一位用于存储字符串结束符'\0'。然后,通过从叶子节点到根节点逆向遍历哈夫曼树,利用一个临时栈S来记录从叶子节点到根节点的路径(通过判断是左孩子还是右孩子来压入0或1)。最后,将栈中的元素依次弹出并存储到HC[i]数组中,形成每个叶子节点对应的哈夫曼编码,并在末尾添加'\0'表示字符串结束。

(五)打印哈夫曼树数组函数(printHaffmamTree)

//打印HT数组
void printHaffmamTree(HuffmanTree& HT, int n) {
    cout << "哈夫曼树如下所示\n";
    cout << "index\tweight\tparent\tlchild\trchild\n";
    for(int i = 1; i <= 2 * n - 1; i++) {
        cout << i << "\t" << HT[i].weight << "\t" << HT[i].parent << "\t" << HT[i].lchild << "\t" << HT[i].rchild << "\t" << endl;
    }
}

这个函数的功能很简单,就是将哈夫曼树节点数组HT的相关信息以清晰的表格形式打印出来。包括节点的索引、权值、父节点、左孩子和右孩子下标等信息,方便我们直观地查看哈夫曼树的结构。

(六)打印哈夫曼编码数组函数(printHaffmanCode)

//打印HC数组
void printHaffmanCode(HuffmanCode& HC, int n) {
    cout << "哈夫曼编码如下所示\n";
    cout << "index\tchar\tcode" << endl;
    for(int i = 1; i <= n; i++) {
        cout << i << "\t" << (char)(i + 96) << "\t";
        int j = 0;
        while(HC[i][j]!= '\0') {
            cout << HC[i][j];
            j++;
        }
        cout << endl;
    }
}

该函数用于打印每个叶子节点对应的哈夫曼编码。首先输出表头信息,然后通过循环遍历每个叶子节点,输出节点的索引、根据索引转换得到的字符(这里通过(char)(i + 96)进行简单转换,假设是按照某种字符编码规则)以及对应的哈夫曼编码内容,方便我们查看每个叶子节点的编码情况。

(七)翻译哈夫曼树函数(HuffmanCodeTranslate)

// 翻译哈夫曼树
void HuffmanCodeTranslate(HuffmanTree& HT, int n) {
    cout << "请输入一个二进制码 " << endl;
    string Code;
    cin >> Code;
    int currentNode = 2 * n - 1; // 从根节点开始,根节点索引假设为2 * n - 1
    for (char bit : Code) {
        if (bit == '0') {
            currentNode = HT[currentNode].lchild;
        } else if (bit == '1') {
            currentNode = HT[currentNode].rchild;
        }

        if (HT[currentNode].lchild == 0 && HT[currentNode].rchild == 0) {
            // 到达叶子节点,输出对应的字符编码
            cout << (char)(current太极 + 96);
            currentNode = 2 * n - 1; // 回到根节点,继续处理下一段编码
        }
    }
}

这个函数实现了对输入的二进制码进行译码的功能。首先获取用户输入的二进制码字符串Code,然后从哈夫曼树的根节点(假设索引为2 * n - 1)开始,根据二进制码的每一位,判断是走向左子树还是右子树。当走到叶子节点(即节点的左右子树都为0)时,输出对应的字符编码,并回到根节点继续处理下一段二进制码,从而将输入的二进制码还原为对应的字符序列。

三、代码存在的一些问题及改进思路

(一)查找最小值函数(SelectMin)的改进

在SelectMin函数中,通过两个嵌套的for循环来查找权值最小和次小且父节点为0的两个节点的方式存在一定的局限性。在后续构建哈夫曼树过程中,可能会出现逻辑上的小瑕疵。例如,在第二次调用SelectMin函数时,可能会因为第一次调用后对节点的父节点进行了设置,导致第二次循环找次小节点时错误地排除了一些原本应该作为候选的节点。

改进思路:可以将两个循环合并为一个循环,在一个循环内同时找到权值最小和次小且父节点为0的两个节点。这样可以避免因为多次调用导致的节点状态变化而引起的错误。

(二)内存管理方面的考虑

在代码中,虽然对哈夫曼树节点数组HT和哈夫曼编码二维数组HC都进行了内存分配,但在程序结束时,没有对这些动态分配的内存进行释放。这可能会导致内存泄漏问题,特别是在长时间运行或频繁调用相关函数的程序中。

改进思路:在程序结束或不再需要使用这些动态分配的内存时,应该及时释放它们。例如,在main函数结束之前,可以添加相应的代码来释放HT和HC所占用的内存。

四、总结

通过对这段C++代码的详细讲解,我们深入了解了哈夫曼树的构建、编码以及译码的实现过程。哈夫曼树作为一种重要的数据结构,在数据压缩、编码理论等领域有着重要的应用。同时,我们也分析了代码中存在的一些问题及改进思路,希望大家在学习和使用哈夫曼树相关知识时,能够更加深入地理解其原理和实现细节,并且能够写出更加完善、高效的代码。

五、代码汇总

#include<bits/stdc++.h>//万能头文件
using namespace std;//命名空间
const int MaxValue = 1e9;

typedef struct {
	int weight;     //权值
	int parent, lchild, rchild;//双亲 左右孩子下标
}HTNode, *HuffmanTree;      //动态分配数组存储哈夫曼树
//指针数组 存放每个编码首元素地址
typedef char **HuffmanCode;//动态分配数组存储哈夫曼编码表

//查找最小值
void SelectMin(HuffmanTree&HT,int k,int &s1,int &s2){
	//初始化为极大的数来查找最小的两个数
	int min1 = MaxValue;
	int min2 = MaxValue;
	//前k个节点中找
	for(int i =1;i<=k;i++){
		if(HT[i].weight<min1&&HT[i].parent==0){//最小值且父母为0
			min1 = HT[i].weight;
			s1 = i;//更新下s1
		}
	}
	for(int j =1;j<=k;j++){
		if(HT[j].weight<min2&&HT[j].parent==0&&j!=s1){//次大的 所以j!=s1
			min2 = HT[j].weight;
			s2 = j;
		}
	}
}

//构造哈夫曼树
void CreateHuffmanTree(HuffmanTree &HT,int n){
	if(n<=1) return ;//叶子节点数量为1 直接退出函数
	int m = 2*n - 1;//HT空间数
	HT = new HTNode[m+1];//申请2n空间(0号不用) 每个节点都是一个只有跟节点的树
	
	//先初始化
	//所有节点的孩子节点 父母节点都为0
	for(int i = 1;i<=m;i++){
		HT[i].lchild = 0;
		HT[i].rchild = 0;
		HT[i].parent = 0;
	}
	
	//再输入每个节点的权值
	//前n个存放叶子节点的权值
	for(int i = 1;i<=n;i++){
		cout<<"请输入第"<<i<<"个节点的权值:";
		cin>>HT[i].weight;
	}
	
	//然后根据哈夫曼树的规则进行一系列操作构建哈夫曼树
	//前n个为未被操作的节点 从n+1个开始构建
	for(int i = n+1;i<=m;i++){
		int s1,s2;
		//在HT中的前i-1个节点中选两个最小且父母节点为0的点
		//因为选出来后会当作HT第i个节点的左右孩子 且插入左右孩子后
		//得到的新节点的parent为0 所以每次从前i-1个节点中找
		SelectMin(HT,i-1,s1,s2);
		//选出来最小节点下标s1 次小节点下标s2后
		HT[s1].parent = i;HT[s2].parent = i;//都接在第i个节点下 相当于删除操作
		HT[i].lchild = s1;HT[i].rchild = s2;//选择操作
		//HT[i]为HT[s1],HT[s2]合并后的节点 weight要合并
		HT[i].weight = HT[s1].weight + HT[s2].weight;//合并操作
	}
}
//保存哈夫曼编码
void CreateHuffmanCode(HuffmanTree&HT,int n,HuffmanCode&HC){
	// 先为HC分配内存,假设每个编码最长不超过n位
	HC = new char *[n + 1];
	for (int i = 1; i <= n; i++) {
		HC[i] = new char[n + 1];  // 多分配一位用于存储字符串结束符'\0'
	}
	//从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码
	stack<char>S;//临时栈 用来存放每个跟节点的逆向路径后正向输出
	for(int i = 1;i<=n;i++){//n个叶子节点对应的哈夫曼编码
		int c = i;//当前节点
		int p = HT[i].parent;//向上查找当前节点的父母节点
		while(p!=0){//当前节点的父母节点还不是根节点时
			if(HT[p].lchild == c) S.push('0');//左0
			else if(HT[p].rchild == c) S.push('1');//右1
			c = p;p = HT[c].parent;//向上倒推
		}//此时S中存放的为第i个节点的逆向路径
		
		//正向存储在HC[i][…]中
		int j =0;
		while(!S.empty()){
			HC[i][j++] = S.top();
			S.pop();
		}
		HC[i][j] = '\0';
	}
}
//打印HT数组
void printHaffmamTree(HuffmanTree&HT,int n){
	cout<<"哈夫曼树如下所示\n";
	cout<<"index\tweight\tparent\tlchild\trchild\n";
	for(int i = 1;i<=2*n-1;i++){
		cout<<i<<"\t"<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<"\t"<<endl;
	}
}
//打印HC数组
void printHaffmanCode(HuffmanCode&HC,int n){
	cout<<"哈夫曼编码如下所示\n";
	cout<<"index\tchar\tcode"<<endl;
	for(int i = 1;i<=n;i++){
		cout<<i<<"\t"<<(char)(i+96)<<"\t";
		int j = 0;
		while(HC[i][j]!='\0'){
			cout<<HC[i][j];
			j++;
		}
		cout<<endl;
	}
}
// 翻译哈夫曼树
void HuffmanCodeTranslate(HuffmanTree& HT, int n) {
	cout << "请输入一个二进制码 " << endl;
	string Code;
	cin >> Code;
	int currentNode = 2 * n - 1; // 从根节点开始,根节点索引假设为2*n - 1
	for (char bit : Code) {
		if (bit == '0') {
			currentNode = HT[currentNode].lchild;
		} else if (bit == '1') {
			currentNode = HT[currentNode].rchild;
		}
		
		if (HT[currentNode].lchild == 0 && HT[currentNode].rchild == 0) {
			// 到达叶子节点,输出对应的字符编码
			cout << (char)(currentNode + 96);
			currentNode = 2 * n - 1; // 回到根节点,继续处理下一段编码
		}
	}
}
int main(){
	int n;//叶子节点个数
	cout<<"请输入您所要构建的哈夫曼树的叶子节点的个数:";
	cin>>n;
	HuffmanTree HT;
	HuffmanCode HC;
	//构建哈夫曼树
	CreateHuffmanTree(HT,n);
	//打印HT数组
	printHaffmamTree(HT,n);
	//构建哈夫曼编码
	CreateHuffmanCode(HT,n,HC);
	//打印HC数组
	printHaffmanCode(HC,n);
	//译码
	HuffmanCodeTranslate(HT,n);
	
	return 0;
}

运行结果如下所示

输入
8
5
29
7
8
14
23
3
11
代表有8个叶子节点 分别是 5,29,7,5,14,23,3,11

代码运行截图

哈夫曼树及哈夫曼树编码译码详解 使用链表形式,实现哈夫曼树的构建及编码译码 阅读详情

相关推荐

数据结构实验2:哈夫曼树应用

数据结构实验2 题目要求 实现一个哈夫曼编码系统,系统包括以下功能: (1) 字符信息统计:读取待编码的源文件SourceFile.txt,统计出现的字符及其频率。 (2) 建立哈夫曼树:根据统计结果建立哈夫曼树以及哈夫曼码表,将各字符对应的编码表保存在文件Code.txt中。 (3) 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile...

BlackCarDriver的博客 6018

数据结构-构造哈夫曼树【详解+代码+图示】一文解惑!

重复循环"爸爸去哪儿"这个过程

weixin_75202470的博客 1万+

数据结构 哈夫曼树的建立

实验4 哈夫曼树的建立 一、实验目的 1. 理解哈夫曼树及其应用。 2. 掌握生成哈夫曼树的算法。 二、实验原理 构造哈夫曼树就是找带全路径长度最短的树,再根据构造出来的树找出结点对应的哈夫曼编码 (1)Select()函数:从无双亲的结点中选出权值最小的一个 实现步骤:先假设一个无双亲的结点k为最小结点,接着遍历所有无双亲的结点,只要检查到某个结点的权值比当前结点k的权值更小,

菜鸟小芝 4109

哈夫曼树详解及其应用(哈夫曼编码)

一,哈夫曼树的基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径 结点的路径长度:两结点之间路径上的分支数 树的路径长度:从树根到每一个结点的路径长度之和.记作:TL 权(weight):将树中结点赋给一个有着某种含义的数值,则这个数值秒针为该结点的权 结点的带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积. 树的带权路径长度:树中所有叶子结点的带权路径长度之和.记作:WPL(Weighted Path Length) 哈夫曼树:最优树(带权路径长度(WP

any_ways的博客 7万+

哈夫曼树——————数据结构作业

实现一个哈夫曼编码系统,系统包括以下功能: 字符信息统计:读取待编码的源文件SourceFile.txt,统计出现的字符及其频率。 建立哈夫曼树:根据统计结果建立哈夫曼树。 建立哈夫曼码表:利用得到的哈夫曼树,将各字符对应的编码表保存在文件Code.txt中。 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile.txt。 Sourc...

鸿杰 的博客 8556

哈夫曼树的构造和显示

写出构造一棵哈夫曼树,并根据哈夫曼树求哈夫曼编码的算法。 【实验要求】 用户键盘输入若干个整数作为待编码字符的权值,程序建立哈夫曼树并输出各字符的哈夫曼编码。

【数据结构——哈夫曼树及其应用】

【数据结构——哈夫曼树及其应用】一、哈夫曼树的基本概念二级目录三级目录二、哈夫曼树的构造算法二级目录三级目录三、哈夫曼编码二级目录三级目录 一、哈夫曼树的基本概念 二级目录 三级目录 二、哈夫曼树的构造算法 二级目录 三级目录 三、哈夫曼编码 二级目录 三级目录 ...

lflcodeplus的博客 6268

ADS 使用调整器动态调参教程(Tuning)

ADS动态调参教程

weixin_42845306的博客 1万+

实验五 哈夫曼树 (C++)

1、实验目的: (1)理解哈夫曼树的概念、结构特性和哈夫曼编码原理; (2)掌握构造哈夫曼树的基本方法; (3)掌握运用哈夫曼树进行哈夫曼编码的方法。 2.、实验内容(实验题目与说明): 根据哈夫曼(Huffman)编码的原理,编写一个程序,在用户输入节点权重的基础 上建立它的哈夫曼编码。哈夫曼编码树是左分支代表 0,右分支代表 1,从根结点到每个叶子结点所经过的路径组成的 0 和 1 的序列便为该叶子结点对应字符的编码,称为哈夫曼编码。 3.代码 #include<stdio.h> #incl

weixin_44222391的博客 6291

新手必看:用Simulink搭建飞跨电容三电平逆变器的完整流程(附SPWM配置技巧)

本文详细介绍了使用Simulink搭建飞跨电容三电平逆变器(FCNPC)的完整流程,特别聚焦于SPWM调制策略的配置技巧。通过模块拆解、参数设置和波形优化的三步法,配合实操截图和典型参数表,帮助新手快速掌握多电平逆变器的建模与仿真技能,适用于电力电子学习和项目开发。

weixin_30664051的博客 284

Unity游戏Mono注入实战:从反编译到功能扩展

本文详细介绍了Unity游戏Mono注入的完整实战流程,从使用dnSpy反编译游戏核心逻辑,到编写自定义C#功能DLL,再到利用SharpMonoInjector进行动态注入。文章深入讲解了如何通过Harmony库拦截修改游戏方法,并介绍了使用MelonLoader框架和UnityExplorer进行高级模组开发与调试,最终通过一个游戏对象透视(ESP)案例演示了功能扩展的实现。

weixin_29018335的博客 458

数据结构哈夫曼树实验报告

实验目的及要求 目的:熟练掌握二叉树应用(Huffman编码)的基本算法实现;进一步理解哈夫曼树的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力 要求:(1).假设文档内容从键盘输入; (2).设计哈夫曼算法的存储结构; (3).设计哈夫曼编码和解码算法; (4).分析使劲按复杂度和空间复杂度。 实验步骤 1.实验问题分析 程序是通过利用二叉树结构实现哈夫曼编码和译码,并且程序需具有以下要求: (1)初始化:能够让用户输入字符和相应字符的频度来初始化,并建立哈夫曼树。

mariodf的博客 2万+

嵌入式人工智能(18-基于树莓派4B的继电器JQC-3FF-S-Z)

本次实验的输出端控制不会接强电,就用LED灯来模拟即可,由于我那个流水灯模块是低电平点亮,所以接线稍有不同,同学们注意。只有继电器吸合,输出端的NO与COM就导通,给LED低电平然后就亮,否则继电器断开,NO与COM不导通,LED不亮。原理都一样,控制电流的接通与断开,这个模块看起来还简单点,毕竟还有2个指示灯,下端IN如接上电源红灯亮,继电器动作有电流通过绿灯亮。在实际应用中,可以通过编程控制继电器的通断状态,例如在Python编程中设置继电器模块的通断时间,从而实现自动化控制。

u010152658的博客 2530

基于哈夫曼树的数据压缩算法

计算机科学与技术系 实 验 报 告 专业名称 计算机科学与技术 课程名称 数据结构与算法 班 级 17计科2班 综合实验2 基于哈夫曼树的数据压缩算法 实验日期 2019.04.29 综合实验二 基于哈夫曼树的数据压缩算法 一、实验目的 1.掌握哈夫曼树的构造算法 2.掌握哈夫曼编码的构造算法 二、实验内容 输入一串字符串,根据给...

zzzley的博客 8776

论文笔记:Group Equivariant Convolutional Networks

Group Equivariant Convolutional Networks 1、四个问题 要解决什么问题? 对卷积神经网络进行扩展,并提出一个在特定的变换(旋转、平移等,也可表示为一个特殊的群)下具有等变性的网络。 用了什么方法解决? 提出了一种新的卷积神经网络结构——群等变卷积神经网络(Group equivariant Convolutional Neural Network)...

hongbin_xu的博客 1万+

YOLOv11模型改进-模块-引入特征细化模块FRFN 解决小目标、遮挡等问题

FRFN 是一种专门设计的深度学习结构,旨在提高图像处理任务中的特征表示能力。它的核心设计理念是通过逐层细化和优化特征图,从而实现更高的分类和检测精度。1. 特征提取层:通过卷积层提取初始特征,并进行批量归一化以增强稳定性。2. 特征细化模块:在每个模块中,当前层特征图与前一层特征图进行融合,以强化特征表示。3. 跳跃连接:通过跳跃连接保留多尺度信息,帮助缓解深层网络中的信息丢失。4. 非线性激活:使用激活函数(如ReLU)增加模型的非线性能力。5. 输出层。

qq_64693987的博客 3336

哈夫曼树编码-C语言

哈夫曼树编码 1.实验目的 了解二叉树的定义,理解二叉树的基本性质和存储结构,掌握哈夫曼树的构造,实现哈夫曼编码与译码算法。 2.实验内容 从键盘输入一串电文字符与权值,输出对应的哈夫曼编码;从键盘输入一串二进制代码,输出对应的电文字符串。具体步骤如下: 构造一棵哈夫曼树; 实现哈夫曼编码; 对哈夫曼编码生成的二进制串进行译码; 要求程序中字符和权值是可变的,实现程序的灵活性。

小北的博客 5939

SAP 行业扫盲系列之一:SAP 从业者的分类

本文简单介绍了 SAP 从业者的分类,限于笔者狭隘的视角,可能存在遗漏或者不恰当的地方,希望大家在评论区指出。 那些在知乎咨询上向我提问关于进入 SAP 行业建议的朋友们,也请大家提问时注明自己想具体从事 SAP 行业哪一类的工作,这样才能得到更让你们满意的回复。感谢阅读。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1588

【树】哈夫曼树及其构造

1.哈夫曼树的基本概念 结点间的路径和路径长度 路径是指从一个结点到另一个结点之间的分支序列 路径长度是指从一个结点到另一个结点所经过的分支数目。 结点的权和带权路径长度 在实际的应用中,人们==给树的每个结点赋予一个具有某种实际意义的实数,称该实数为这个结点的权。==在树型结构中,把从树根到某一结点的路径长度与该结点的权 的乘积,叫做该结点的带权路径长度。  树的带权路径长度 树的带权路径...

weixin_45765128的博客 4万+

【RT-DETR涨点改进】独家Conv改进篇 | 来自TIP 2024顶刊| 引入 DEConv细节增强卷积模块, 能够恢复更多细节信息,提升小目标检测精度、含多种不同模型改进点

本文提出了一种细节增强卷积(DEConv)模块,通过融合多种差异卷积(CDC、ADC、HDC、VDC)来增强图像特征表示能力,特别在边缘和纹理细节提取方面表现突出。该模块采用重参数化技术,在不增加计算成本的情况下,将先验信息融入常规卷积层,显著提升了RT-DETR模型在模糊或遮挡场景下的目标检测精度。实验验证了DEConv在多种骨干网络(ResNet18/50、HGNet等)中的有效性,为实时目标检测系统提供了轻量高效的改进方案。

Ai缝合怪、助力小伙伴高效发论文 449

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【数据结构】哈夫曼树与哈夫曼编码的Python实现及应用

用python实现哈夫曼树与哈夫曼编码,并通过哈夫曼编码压缩核酸序列信息。

weixin_43643877的博客 2549

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

哈夫曼树和哈夫曼编码

本文主要是用C语言实现数据结构之哈夫曼树,同时对应哈夫曼编码。

墨城烟柳ベ旧人殇的博客 5012

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

数据结构实验五:哈夫曼树的设计及实现

实验五 哈夫曼树的设计及实现 一、实验目的 1. 掌握哈夫曼树的构造算法,理解二叉树的应用; 2. 掌握哈夫曼编码的构造算法。 二、实验内容 输入一串字符串,根据给定的字符串中字符出现的频率建立相应的哈夫曼树,构造哈夫曼编码表,在此基础上可以对压缩文件进行压缩(即编码)。 已知字符串中出现的字符为A、B、C、D、E、F、G、H,其相应的权值为 7、19、2、6、32、3、21、10。

qq_45158661的博客 1万+

数据结构集中实践 哈夫曼树实验报告

二、实验内容 1.根据给出的字符以及这些字符的使用频率构建哈夫曼树。 2.根据哈夫曼树对字符进行哈夫曼编码,并保存这些编码。 三、实验原理、方法和手段 试构造出问题模型,并编程实现这一问题的求解。根据实验内容编程,上机调试、得出正确的运行程序;编译运行程序,观察运行情况和输出结果。 六、实验步骤 1. 建立哈夫曼树的存储结构和哈夫曼编码的存储结构。 2. 建立哈夫曼树的...

WonderKing'blog 1万+

【哈夫曼树及其应用 c语言】

欲发一封内容为 AABBCAB ……(共长 100 字符,其中:A 、 B 、 C 、 D 、 E 、 F 分别有 7 、 9 、 12 、 22 、 23、 27 个)的电报报文,实现哈夫曼编码和译码。

qq_53045580的博客 4328

通识哈夫曼树及其应用,一起来构造属于自己的哈夫曼树

本文主要介绍了哈夫曼树的背景、算法构造以及实际应用,然后,让我们一起来编写自己的哈夫曼树吧!!!!

Williamtym的博客 2867
上一篇: 二叉树的链式表示及实现(实验6--作业)
下一篇: 图的存储、遍历以及Dijkstra/Floyd/Kruskal/Prim/拓扑排序/关键路径(实验8--作业)
ByteMaster_
博客等级 码龄3年 328粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值