哈夫曼编码算法的实现用C++编写
c语言哈夫曼树的构造及编码
c语言哈夫曼树的构造及编码一、哈夫曼树概述哈夫曼树是一种特殊的二叉树,它的构建基于贪心算法。
它的主要应用是在数据压缩和编码中,可以将频率高的字符用较短的编码表示,从而减小数据存储和传输时所需的空间和时间。
二、哈夫曼树的构造1. 哈夫曼树的定义哈夫曼树是一棵带权路径长度最短的二叉树。
带权路径长度是指所有叶子节点到根节点之间路径长度与其权值乘积之和。
2. 构造步骤(1) 将待编码字符按照出现频率从小到大排序。
(2) 取出两个权值最小的节点作为左右子节点,构建一棵新的二叉树。
(3) 将新构建的二叉树加入到原来排序后队列中。
(4) 重复上述步骤,直到队列只剩下一个节点,该节点即为哈夫曼树的根节点。
3. C语言代码实现以下代码实现了一个简单版哈夫曼树构造函数:```ctypedef struct TreeNode {int weight; // 权重值struct TreeNode *leftChild; // 左子节点指针struct TreeNode *rightChild; // 右子节点指针} TreeNode;// 构造哈夫曼树函数TreeNode* createHuffmanTree(int* weights, int n) {// 根据权值数组构建节点队列,每个节点都是一棵单独的二叉树TreeNode** nodes = (TreeNode**)malloc(sizeof(TreeNode*) * n);for (int i = 0; i < n; i++) {nodes[i] = (TreeNode*)malloc(sizeof(TreeNode));nodes[i]->weight = weights[i];nodes[i]->leftChild = NULL;nodes[i]->rightChild = NULL;}// 构建哈夫曼树while (n > 1) {int minIndex1 = -1, minIndex2 = -1;for (int i = 0; i < n; i++) {if (nodes[i] != NULL) {if (minIndex1 == -1 || nodes[i]->weight < nodes[minIndex1]->weight) {minIndex2 = minIndex1;minIndex1 = i;} else if (minIndex2 == -1 || nodes[i]->weight < nodes[minIndex2]->weight) {minIndex2 = i;}}}TreeNode* newNode =(TreeNode*)malloc(sizeof(TreeNode));newNode->weight = nodes[minIndex1]->weight + nodes[minIndex2]->weight;newNode->leftChild = nodes[minIndex1];newNode->rightChild = nodes[minIndex2];// 将新构建的二叉树加入到原来排序后队列中nodes[minIndex1] = newNode;nodes[minIndex2] = NULL;n--;}return nodes[minIndex1];}```三、哈夫曼编码1. 哈夫曼编码的定义哈夫曼编码是一种前缀编码方式,它将每个字符的编码表示为二进制串。
哈夫曼树及哈夫曼编码的算法实现c语言
哈夫曼树及哈夫曼编码的算法实现c语言1.引言1.1 概述哈夫曼树及哈夫曼编码是数据压缩和编码中常用的重要算法。
哈夫曼树由大卫·哈夫曼于1952年提出,用于根据字符出现的频率构建一种最优的前缀编码方式。
而哈夫曼编码则是根据哈夫曼树构建的编码表将字符进行编码的过程。
在现代通信和计算机领域,数据传输和存储中往往需要大量的空间。
为了有效利用有限的资源,减少数据的存储和传输成本,数据压缩成为一个重要的技术。
而哈夫曼树及哈夫曼编码正是数据压缩中常用的技术之一。
哈夫曼树的概念及原理是基于字符的频率和概率进行构建的。
在哈夫曼树中,字符出现频率越高的节点越接近根节点,出现频率越低的节点离根节点越远。
这种构建方式保证了哈夫曼树的最优性,即最小化编码的总长度。
哈夫曼编码的算法实现是根据哈夫曼树构建的编码表进行的。
编码表中,每个字符都与一段二进制编码相对应。
在进行数据压缩和解压缩时,通过查表的方式将字符转化为相应的二进制编码,或将二进制编码解析为原始字符。
本文旨在介绍哈夫曼树及哈夫曼编码的概念和原理,并通过C语言实现算法。
通过深入理解哈夫曼树及哈夫曼编码的实现过程,可以更好地理解数据压缩和编码的原理,为后续的研究和应用提供基础。
接下来,我们将首先介绍哈夫曼树的概念和原理,然后详细讲解哈夫曼编码的算法实现。
最后,我们将总结哈夫曼树及哈夫曼编码的重要性,并提出对哈夫曼树和哈夫曼编码进一步研究的方向。
让我们一起深入探索哈夫曼树及哈夫曼编码的奥秘吧!1.2 文章结构文章结构部分的内容可以包括以下内容:文章结构部分主要介绍了本文的组织结构和各个章节的内容概述,以帮助读者更好地理解全文的逻辑结构和内容安排。
首先,本文包括引言、正文和结论三个部分。
引言部分主要对哈夫曼树及哈夫曼编码的算法实现进行了概述,包括相关的概念、原理和目的。
正文部分则深入介绍了哈夫曼树的概念和原理,以及哈夫曼编码的算法实现。
最后,结论部分对本文的主要内容进行了总结,并提出了对哈夫曼树和哈夫曼编码的进一步研究方向。
基于C语言的哈夫曼编码的实现
基于C语言的哈夫曼编码的实现摘要:介绍了哈夫曼编码的思想,以及利用C语言实现哈夫曼编码的详细过程。
关键词:哈夫曼编码;权值;哈夫曼树;二叉树0引言数据通讯中,经常需要将传送的字符转换为由二进制字符0或1组成的二进制串,我们称此过程为编码。
而哈夫曼树可以用来构造代码总长度最短的编码方案,将需要编码的字符作为叶节点,字符在电文中出现的频率作为权值,构造一颗二叉树,规定哈夫曼树的左分支为0,右分支为1,则从根节点到每个叶结点所经历的分支对应的0和1组成的数列变为该结点对应的字符编码。
这种总长度最短的不等长编码就叫做哈夫曼编码。
利用哈夫曼编码通信可以大大提高通信利用率,缩短通信传输时间,降低传输成本。
1问题描述利用C语言编程实现哈夫曼编码。
要求:用户输入各字母及使用频率(或频数),用程序输出二进制表示的哈夫曼编码,并采用菜单和会话方式的界面。
2算法思想(1)哈夫曼编码根据与n个权值{w1,w2,……wn}对应的n 个结点构成n棵二叉树的森林,F= {T1,T2,……Tn},其中每棵二叉树Ti(1<=I<=n)都有一个权值为wi的根结点,其左右子树均为空。
(2)在森林F中选出两棵根结点权值最小的树作为一棵新树的左右子树,且置新树的附加根结点的权值为其左右树上根结点的权值之和。
(3)从F中删除这两棵树,同时把新树加入F中。
(4)重复(2)和(3)直到只含有一棵树为止,此时便是哈夫曼树。
(5)树从根到每个叶子都有一条路径,对路径上的各分支约定,指向左子树的分支表示‘0’码,指向右子树的分支表示‘1’码。
(6)取每条路径上‘0’或‘1’的序列作为各个叶子对应的字符编码,这就是哈夫曼编码。
3逻辑设计树的逻辑结构是层次结构,树中有且仅有一个没有前驱的结点ht[0]称为树的根,除根ht[0]以外的每个结点都有且只有一个前驱,对于不是根的每一个结点ht[I]都有一个线性序列ht[0],ht[1],……ht[I-1],ht[I] (I>=0),其中ht[I]是ht[I-1]的后继。
哈夫曼树的构造c语言代码
哈夫曼树的构造c语言代码哈夫曼树是一种特殊的二叉树,常被用于数据压缩中。
它的构造过程非常重要,接下来我将用c语言展示如何构造哈夫曼树。
首先,我们需要定义一个结构体作为节点:```struct Node{int weight;//权重int parent;//父节点在数组中的下标int lchild;//左子节点在数组中的下标int rchild;//右子节点在数组中的下标};```然后,我们需要读入数据,计算每个数据的权重,随后用一个数组存储节点信息:```int n;//数据个数int W[maxn];//存储每个数据的权重Node tree[maxn*2-1];//哈夫曼树```接下来,我们需要编写一个函数用来选择权值最小的两个节点,然后将它们合并成一个节点。
```int select_min(Node*tree,int n){int res=-1;int min=INT_MAX;for(int i=0;i<n;i++){if(tree[i].parent!=-1)continue;//跳过已经合并的节点if(tree[i].weight<min){min=tree[i].weight;res=i;}}return res;}void merge_node(Node*tree,int a,int b,int i){tree[a].parent=i;tree[b].parent=i;tree[i].weight=tree[a].weight+tree[b].weight;tree[i].lchild=a;tree[i].rchild=b;}```接下来,我们就可以开始构造哈夫曼树了。
我们先初始化每个节点,将它们都看成一个独立的树,然后选择最小的两个节点进行合并,直到最后只剩下一个树为止。
```void build_tree(Node*tree,int n,int*W){for(int i=0;i<n;i++){tree[i].weight=W[i];tree[i].parent=-1;tree[i].lchild=-1;tree[i].rchild=-1;}for(int i=n;i<(n<<1)-1;i++) {int a=select_min(tree,i);int b=select_min(tree,i);merge_node(tree,a,b,i);}}```最后,我们可以调用build_tree函数来构造哈夫曼树。
哈夫曼编码译码器数据结构C语言
哈夫曼编码译码器数据结构C语言哈夫曼编码译码器数据结构C语言⒈简介本文档旨在介绍一个使用C语言实现的哈夫曼编码译码器的数据结构。
哈夫曼编码是一种用于数据压缩的算法,它通过将频率较高的字符用较短的编码表示,从而实现数据的压缩和解压缩。
⒉哈夫曼编码(Huffman Coding)基本概念⑴字符频率统计在进行哈夫曼编码之前,我们首先需要统计每个字符在待编码的数据中出现的频率。
通过遍历数据,记录每个字符的出现次数,我们可以得到一个字符频率的统计表。
⑵构建哈夫曼树通过字符频率的统计表,我们可以构建一个哈夫曼树。
哈夫曼树是一种二叉树,其中每个叶节点表示一个字符,而每个内部节点表示一个权重,即两个子节点的频率之和。
⑶哈夫曼编码在哈夫曼树构建完成后,我们可以根据树的结构每个字符的编码。
哈夫曼编码的特点是没有任何一个字符的编码是另一个字符编码的前缀,这种编码方式称为前缀编码。
⑷哈夫曼译码根据字符的哈夫曼编码,我们可以将编码后的数据进行解码,还原为原始的数据。
通过遍历哈夫曼树,从根节点开始,根据每个二进制位的取值进行向左或向右的移动,直至叶节点,然后获取该叶节点对应的字符。
⒊数据结构设计⑴结点结构定义一个哈夫曼树的结点结构,包含以下字段:●`char data`:字符●`int frequency`:字符的频率●`int is_leaf`:是否为叶节点●`struct Node left_child`:左子节点●`struct Node right_child`:右子节点⑵频率统计表使用一个数组或链表来记录每个字符的频率统计信息,包含以下字段:●`char data`:字符●`int frequency`:字符的频率⑶编码表使用一个数组或链表来记录每个字符的哈夫曼编码,包含以下字段:●`char data`:字符●`char code`:编码⒋算法流程⑴字符频率统计算法步骤:⒈初始化频率统计表为空。
⒉读取待编码的数据。
用c语言实现哈夫曼编码
用c语言实现哈夫曼编码哈夫曼编码是一种用于无损数据压缩的熵编码算法。
以下是一个简单的使用C语言实现哈夫曼编码的例子。
这个例子只实现了编码过程,没有实现解码过程。
c复制代码#include<stdio.h>#include<stdlib.h>#include<string.h>// 节点结构体typedef struct Node {char data;int freq;struct Node *left, *right;} Node;// 创建新节点Node* newNode(char data, int freq) {Node* node = (Node*) malloc(sizeof(Node));node->data = data;node->freq = freq;node->left = node->right = NULL;return node;}// 计算前缀和int getSum(Node* root) {if (!root) return0;return root->freq + getSum(root->left) + getSum(root->right);}// 创建哈夫曼树Node* createHuffmanTree(char data[], int freq[], int size) { if (size == 0) return NULL;Node *left = newNode(data[size-1], freq[size-1]);Node *right = createHuffmanTree(data, freq, size-1);Node *top = newNode(0, getSum(right));top->left = left;top->right = right;return top;}// 打印哈夫曼编码void printHuffmanCode(Node* root, int n, char code[]) {if (!root) return;if (root->data != 0) printf("%c: ", root->data);code[n] = root->data;printHuffmanCode(root->left, n+1, code);printHuffmanCode(root->right, n+1, code);}int main() {char data[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};int freq[] = {5, 9, 12, 13, 16, 45};int size = sizeof(data)/sizeof(data[0]);Node* root = createHuffmanTree(data, freq, size);char code[256] = {0}; // 存放哈夫曼编码,初始为空字符串,表示没有编码,对应字符的编码为空字符串。
c++哈夫曼编码与解码的实现
在C++编程中,哈夫曼编码与解码是一个非常重要且有趣的主题。
它涉及到数据压缩和信息传输中的关键技术,对于理解算法和数据结构有着重要的意义。
下面我将详细讨论C++中哈夫曼编码与解码的实现。
1. 哈夫曼编码哈夫曼编码是一种有效的编码方式,用于无损数据压缩。
它通过根据字符出现的频率来构建不等长的编码,将高频字符用短编码表示,低频字符用长编码表示,从而减少数据传输的长度。
在C++中,我们可以通过构建哈夫曼树来实现编码过程。
2. 哈夫曼解码哈夫曼解码是编码的逆过程,它通过哈夫曼树和编码表来将编码还原成原始数据。
在C++中,我们可以使用递归或循环的方式来实现哈夫曼解码算法。
3. 实现思路在C++中实现哈夫曼编码与解码,我们可以首先构建哈夫曼树,然后根据哈夫曼树生成编码表,利用编码表对原始数据进行编码,并提供相应的解码函数进行解压。
在构建哈夫曼树时,可以使用最小堆或优先队列来辅助实现。
4. 代码示例下面是一个简单的C++代码示例,用于实现哈夫曼编码与解码:```cpp// 在这里插入你的代码示例```5. 个人观点我对哈夫曼编码与解码的实现非常感兴趣,它涉及到了树形数据结构、优先队列等知识,并且能够在实际应用中发挥重要作用。
在C++编程中,掌握哈夫曼编码与解码的实现对于提高编程技能和理解数据压缩算法都有着重要的意义。
总结回顾:通过本文的讨论,我们对C++中哈夫曼编码与解码的实现有了更深入的理解。
我们首先了解了哈夫曼编码和解码的基本原理,然后通过代码示例展示了其具体实现方法。
我也共享了自己对这一主题的个人观点和理解。
通过学习和掌握哈夫曼编码与解码的实现,我们可以更好地应用在实际项目中,提高程序的效率和性能。
在这篇文章中,我们全面地讨论了哈夫曼编码与解码的实现方法,并根据指定的主题,让你更深入地理解了这一内容。
希望这篇文章对你有所帮助,也欢迎你在实际项目中尝试应用哈夫曼编码与解码算法,不断提升自己的编程能力。
哈夫曼编码与解码在现代通信和数据存储中起着非常重要的作用。
c++哈夫曼编码的实现
c++哈夫曼编码的实现=================哈夫曼编码是一种非常有效的数据压缩算法,它的主要思想是通过统计数据中各种符号的频率来构建一棵哈夫曼树,从而实现对原始数据的编码。
在C语言中,我们可以使用动态规划来实现哈夫曼编码。
一、哈夫曼编码的基本原理--------------哈夫曼编码是一种可变长度编码,其编码长度取决于原始数据中各个符号的频率。
频率越高的符号,其编码长度越短。
通过统计数据中各个符号的出现频率,我们可以构建出一棵哈夫曼树,这棵树中的每个节点都代表一个符号,节点的权值就是该符号的频率。
通过遍历哈夫曼树,我们可以得到每个符号的编码,从而实现数据的压缩。
二、C语言实现哈夫曼编码------------下面是一个简单的C语言程序,实现了哈夫曼编码的功能:```c#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#define MAX_SYMBOL_COUNT 100 // 最大符号数量#define HUF_TREE_DEPTH 3 // 哈夫曼树深度为3typedef struct Node {char symbol; // 符号struct Node* left; // 左子节点struct Node* right; // 右子节点double frequency; // 频率} Node;// 创建新节点Node* createNode(char symbol, double frequency) {Node* node = (Node*)malloc(sizeof(Node));node->symbol = symbol;node->frequency = frequency;node->left = NULL;node->right = NULL;return node;}// 构建哈夫曼树Node* buildHuffmanTree(char* symbols, int symbolCount) { // 根据频率进行排序,从小到大排列double frequencies[MAX_SYMBOL_COUNT];for (int i = 0; i < symbolCount; i++) {frequencies[i] = symbols[i] == ' ' ? 0.0 : symbols[i] ? symbols[i] : -1; // 检查字符是否存在}qsort(frequencies, symbolCount, sizeof(double), compare); // 使用qsort进行排序Node* root = NULL; // 根节点为空,需要手动构建哈夫曼树int index = 0; // 下一个需要创建节点的索引(0到symbolCount-1之间)double currentFrequency = frequencies[index]; // 当前节点频率(如果不为空)while (index < symbolCount){ // 遍历所有符号和频率,直到遍历完为止if (root == NULL){ // 如果根节点为空,创建根节点并指向当前节点root = createNode(NULL, currentFrequency);} else{ // 如果根节点不为空,查找下一个需要创建节点的索引和当前节点频率是否小于当前节点频率的倒数index++; // 下一个需要创建节点的索引增加一个位置(包括当前节点)if (frequencies[index] / currentFrequency <1.0 / HUF_TREE_DEPTH) { // 如果满足条件,创建新的子节点并递归构建哈夫曼树(当前节点)Node* child = createNode(symbols[index], frequencies[index]); // 创建子节点并保存符号和频率信息if (root->left == NULL){ // 如果当前节点的左子节点为空,将当前节点设置为左子节点并递归构建哈夫曼树(左子树)root->left = child;} else{ // 如果当前节点的右子节点为空,将当前节点设置为右子节点并递归构建哈夫曼树(右子树)root->right = child;} // 更新根节点的左右子节点信息并递归构建哈夫曼树(父节点)} else{ // 如果当前节点不足以生成新的子节点(由于被优先排序)继续处理下一个节点 currentFrequency = frequencies[index]; // 将当前节点的频率设置为下一个需要创建节点的频率(避免重复处理同一个符号)} // 更新索引和当前频率信息(继续处理下一个符号)} // 结束while循环(处理完所有符号和频率)}。
哈夫曼编码c语言代码
哈夫曼编码c语言代码1.统计数据中每个字符出现的次数。
2.根据每个字符出现的次数建立哈夫曼树。
3.根据哈夫曼树构建每个字符的编码,相同的字符具有不同的编码。
4.用编码替换原数据中的字符。
根据上述步骤,我们可以得到以下的C语言实现。
C语言实现哈夫曼编码在C语言中,我们可以使用结构体来表示哈夫曼树节点及其信息:```ctypedef struct node 。
char content;int freq;struct node某 left;struct node某 right;} node;```其中content表示节点所代表的字符,freq表示该字符在数据中出现的次数,left和right分别指向节点的左右子节点。
我们可以使用一个链表来存储所有的字符及其出现的次数:```ctypedef struct listNode 。
node某 n;struct listNode某 ne某t;} listNode;```这个链表可以通过遍历数据,统计每个字符出现的次数来构建。
我们可以使用一个堆来存储所有的树节点,每次从堆中取出频率最小的两个节点,构建一个新的节点,然后将这个新节点插入堆中。
重复这个过程直到堆中只剩下一个根节点,这个节点就是哈夫曼树的根节点。
```ctypedef struct heap 。
int size;node某某 nodes;} heap;```定义堆的时候,size表示堆中节点的数量,nodes是一个数组,存储所有的节点。
我们可以使用一棵二叉堆来实现堆的操作,即将频率最小的节点放在堆的顶部。
构建好哈夫曼树后,我们可以通过遍历树来给每个字符一个独一无二的编码。
编码的时候,我们可以使用一个栈来存储每个节点的信息,然后倒序输出栈中的内容来得到编码。
最后,我们可以使用编码替换原数据中的字符。
在解码的时候,我们只需要将编码反向遍历树即可还原原始数据。
总结。
哈夫曼编码详解(C语言实现)
哈夫曼编码详解(C语言实现)哈夫曼编码是一种常见的前缀编码方式,被广泛应用于数据压缩和传输中。
它是由大卫·哈夫曼(David A. Huffman)于1952年提出的,用于通过将不同的字符映射到不同长度的二进制码来实现数据的高效编码和解码。
1.统计字符频率:遍历待编码的文本,记录每个字符出现的频率。
2.构建哈夫曼树:根据字符频率构建哈夫曼树,其中出现频率越高的字符位于树的较低层,频率越低的字符位于树的较高层。
3.生成编码表:从哈夫曼树的根节点开始,遍历哈夫曼树的每个节点,为每个字符生成对应的编码。
在遍历过程中,从根节点到叶子节点的路径上的“0”表示向左,路径上的“1”表示向右。
4.进行编码:根据生成的编码表,将待编码的文本中的每个字符替换为对应的编码。
5.进行解码:根据生成的编码表和编码结果,将编码替换为原始字符。
下面是一个用C语言实现的简单哈夫曼编码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>//定义哈夫曼树的节点结构体typedef struct HuffmanNodechar data; // 字符数据int freq; // 字符出现的频率struct HuffmanNode *left; // 左子节点struct HuffmanNode *right; // 右子节点} HuffmanNode;//定义编码表typedef structchar data; // 字符数据char *code; // 字符对应的编码} HuffmanCode;//统计字符频率int *countFrequency(char *text)int *frequency = (int *)calloc(256, sizeof(int)); int len = strlen(text);for (int i = 0; i < len; i++)frequency[(int)text[i]]++;}return frequency;//创建哈夫曼树HuffmanNode *createHuffmanTree(int *frequency)//初始化叶子节点HuffmanNode **leaves = (HuffmanNode **)malloc(256 * sizeof(HuffmanNode *));for (int i = 0; i < 256; i++)if (frequency[i] > 0)HuffmanNode *leaf = (HuffmanNode*)malloc(sizeof(HuffmanNode));leaf->data = (char)i;leaf->freq = frequency[i];leaf->left = NULL;leaf->right = NULL;leaves[i] = leaf;} elseleaves[i] = NULL;}}//构建哈夫曼树while (1)int min1 = -1, min2 = -1;for (int i = 0; i < 256; i++)if (leaves[i] != NULL)if (min1 == -1 , leaves[i]->freq < leaves[min1]->freq) min2 = min1;min1 = i;} else if (min2 == -1 , leaves[i]->freq < leaves[min2]->freq)min2 = i;}}}if (min2 == -1)break;}HuffmanNode *parent = (HuffmanNode*)malloc(sizeof(HuffmanNode));parent->data = 0;parent->freq = leaves[min1]->freq + leaves[min2]->freq;parent->left = leaves[min1];parent->right = leaves[min2];leaves[min1] = parent;leaves[min2] = NULL;}HuffmanNode *root = leaves[min1];free(leaves);return root;//生成编码表void generateHuffmanCode(HuffmanNode *root, HuffmanCode *huffmanCode, char *code, int depth)if (root->left == NULL && root->right == NULL)code[depth] = '\0';huffmanCode[root->data].data = root->data;huffmanCode[root->data].code = strdup(code);return;}if (root->left != NULL)code[depth] = '0';generateHuffmanCode(root->left, huffmanCode, code, depth + 1);}if (root->right != NULL)code[depth] = '1';generateHuffmanCode(root->right, huffmanCode, code, depth + 1);}//进行编码char *encodeText(char *text, HuffmanCode *huffmanCode)int len = strlen(text);int codeLen = 0;char *code = (char *)malloc(len * 8 * sizeof(char));for (int i = 0; i < len; i++)strcat(code + codeLen, huffmanCode[(int)text[i]].code);codeLen += strlen(huffmanCode[(int)text[i]].code);}return code;//进行解码char* decodeText(char* code, HuffmanNode* root) int len = strlen(code);char* text = (char*)malloc(len * sizeof(char)); int textLen = 0;HuffmanNode* node = root;for (int i = 0; i < len; i++)if (code[i] == '0')node = node->left;} elsenode = node->right;}if (node->left == NULL && node->right == NULL) text[textLen] = node->data;textLen++;node = root;}}text[textLen] = '\0';return text;int maichar *text = "Hello, World!";int *frequency = countFrequency(text);HuffmanNode *root = createHuffmanTree(frequency);HuffmanCode *huffmanCode = (HuffmanCode *)malloc(256 * sizeof(HuffmanCode));char code[256];generateHuffmanCode(root, huffmanCode, code, 0);char *encodedText = encodeText(text, huffmanCode);char *decodedText = decodeText(encodedText, root);printf("Original Text: %s\n", text);printf("Encoded Text: %s\n", encodedText);printf("Decoded Text: %s\n", decodedText);//释放内存free(frequency);free(root);for (int i = 0; i < 256; i++)if (huffmanCode[i].code != NULL)free(huffmanCode[i].code);}}free(huffmanCode);free(encodedText);free(decodedText);return 0;```上述的示例代码实现了一个简单的哈夫曼编码和解码过程。
算法设计与分析试卷试题(A)(附答案)
chengcheng算法分析考试试卷(A卷)课程名称算法分析编号题号一二三四总分得分评阅人一、填空题(每小题3分,共30分)1、一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
2、这种不断回头寻找目标的方法称为回溯法。
3、直接或间接地调用自身的算法称为递归算法。
4、 记号在算法复杂性的表示法中表示紧致界。
5、由分治法产生的子问题往往是原问题较小模式,这就为使用递归技术提供了方便。
6、建立计算模型的目的是为了使问题的计算复杂性分析有一个共同的客观尺度。
7、下列各步骤的先后顺序是②③④①。
①调试程序②分析问题③设计算法④编写程序。
8、最优子结构性质的含义是问题最优解包含其子问题最优解。
9、贪心算法从初始阶段开始,每一个阶段总是作一个使局部最优的贪心选择。
10、拉斯维加斯算法找到的解一定是正确的。
二、选择题(每小题2分,共20分)1、哈夫曼编码可利用( C )算法实现。
A、分治策略B、动态规划法C、贪心法D、回溯法2、下列不是基本计算模型的是( B )。
A、RAMB、ROMC、RASPD、TM3、下列算法中通常以自顶向下的方式求解最优解的是( C)。
A、分治法B、动态规划法C、贪心法D、回溯法chengcheng 4、在对问题的解空间树进行搜索的方法中,一个活结点有多次机会成为活结点的是( A )A、回溯法B、分支限界法C、回溯法和分支限界法D、动态规划5、秦始皇吞并六国使用的远交近攻,逐个击破的连横策略采用了以下哪种算法思想? BA、递归;B、分治;C、迭代;D、模拟。
6、FIFO是( A )的一搜索方式。
A、分支界限法B、动态规划法C、贪心法D、回溯法7、投点法是( B )的一种。
A、分支界限算法B、概率算法C、贪心算法D、回溯算法8、若线性规划问题存在最优解,它一定不在( C )A.可行域的某个顶点上 B.可行域的某条边上 C.可行域内部 D.以上都不对9、在一般输入数据的程序里,输入多多少少会影响到算法的计算复杂度,为了消除这种影响可用( B )对输入进行预处理。
c语言实现哈夫曼编码
c语言实现哈夫曼编码一、概述哈夫曼编码是一种常用的无损数据压缩算法,其原理是基于字符的出现概率来构建编码表,从而实现数据的压缩。
本教程将介绍如何使用C语言实现哈夫曼编码算法。
二、算法原理哈夫曼编码算法的基本思想是:将字符按照出现概率的大小进行排序,然后构建一个树状结构,每个节点代表一个字符,节点的左子节点和右子节点分别代表字符的频率较小和较大的分支。
最终,通过路径进行解码即可还原出原始数据。
三、实现步骤1.统计字符频率,构建字符频率表;2.按照频率从小到大排序,构建哈夫曼树;3.根据哈夫曼树构建编码表,将字符映射为编码;4.实现解码过程,还原出原始数据。
四、代码实现下面是一个简单的C语言实现哈夫曼编码的示例代码:```c#include<stdio.h>#include<stdlib.h>#include<ctype.h>#defineMAX_CHARS1000//最大字符数#defineMAX_FREQ100//最大频率值//字符频率表intfreq[MAX_CHARS+1];//构建哈夫曼树函数structnode{charch;intfreq;structnode*left,*right;};structnode*build_huffman_tree(intfreq[],intn){structnode*root=(structnode*)malloc(sizeof(structnode));root->freq=freq[0];//根节点的频率为最小的频率值root->left=root->right=NULL;for(inti=1;i<=n;i++){if(freq[i]==root->freq){//如果当前字符的频率与根节点的频率相同,则添加到左子树或右子树中if(i<n&&freq[i]==freq[i+1]){//如果当前字符的频率与下一个字符的频率相同,则添加到左子树中root->left=(structnode*)malloc(sizeof(structnode));root->left->ch=i+'a';//左子节点的字符为当前字符的下一个字符(假设所有字符都是小写字母)root->left->left=root->left->right=NULL;//左子树为空树i++;//跳过下一个字符,继续寻找下一个不同的频率值}else{//如果当前字符的频率与下一个字符的频率不相同,则添加到右子树中root->right=(structnode*)malloc(sizeof(structnode));root->right->ch=i+'a';//右子节点的字符为当前字符root->right->left=root->right->right=NULL;//右子树为空树}}elseif(freq[i]<root->freq){//如果当前字符的频率小于根节点的频率,则添加到左子树中root->left=(structnode*)malloc(sizeof(structnode));root->left->ch=i+'a';//左子节点的字符为当前字符的下一个字符(假设所有字符都是小写字母)root->left->left=build_huffman_tree(freq,i);//子树的左孩子为当前字符构成的右子树节点和子哈夫曼树的左孩子合并得到的左孩子节点,这个步骤继续调用本函数,从而继续构建右子树的下一级和再下一级,最终实现三级左右子的嵌套式结构树型哈夫曼编码)注:这种思想并非标准的哈夫曼编码)//子树的右孩子为当前节点(即当前字符)构成的右子树节点和子哈夫曼树的右孩子节点合并得到的右孩子节点)注:这种思想并非标准的哈夫曼编码)//子树的左孩子为空树)注:这种思想并非标准的哈夫曼编码)根节点的频率是根节点的最小频率值(因为构建哈夫曼树的过程中总是从最小的频率值开始)根节点的左子树是构建出的三级左右子的嵌套式结构树型哈夫曼编码根节点的右子树为空树(假设所有字符都是小写字母)在添加左子节点后需要调用本函数构建右子树的下一级和再下一级来得到三级左右子的嵌套式结构。
哈夫曼编码译码器数据结构C语言
一、需求分析目前,进行快速远距离通信的主要手段是电报,即将需传送的文字转化成由二级制的字符组成的字符串.例如,假设需传送的电文为“ABACCDA",它只有4种字符,只需两个字符的串,便可以分辨。
假设A 、B 、C 、D 、的编码分别为00,01,10和11,则上述7个字符的电文便为“00010010101100”,总长14位,对方接受时,可按二位一分进行译码。
当然,在传送电文时,希望总长尽可能地短.如果对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,则传送电文的总长便可减少。
如果设计A 、B 、C 、D 的编码分别为0,00,1,01,则上述7个字符的电文可转换成总长为9的字符串“000011010"。
但是,这样的电文无法翻译,例如传送过去的字符串中前4个字符的字串“0000”就可以有很多种译法,或是“AAAA ”或者“BB ”,或者“ABA ”等.因此,若要设计长短不等的编码,则必须是任一字符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码。
然而,如何进行前缀编码就是利用哈夫曼树来做,也就有了现在的哈夫曼编码和译码.二、概要设计利用哈夫曼树编/译码 (一)、建立哈夫曼树 (二)、对哈夫曼树进行编码 (三)、输出对应字符的编码 (四)、译码过程主要代码实现: struct code //结构体的定义 { char a ; int w ; int parent; int lchild; int rchild; };void creation(code *p,int n ,int m ); //建立哈夫曼树 void coding (code *p,int n ); //编码 void display (code *p ,int n ,int m); //输出函数 void translate (char **hc,code *p,int n); //译码三、 详细设计(一)、建立哈夫曼树2 3 4 5 * * * 6 7序号:权值: 1 2 3 4 3 6 10 6 图3-1 图(二)、对哈夫曼树进行编码 主要代码实现: for(c=i,f=p [i ].parent;f!=0;c=f ,f=p [f ]。
c语言实现构造哈夫曼树代码
c语言实现构造哈夫曼树代码一、哈夫曼树简介哈夫曼树是一种特殊的二叉树,其每个叶子节点都对应一个权值,而非叶子节点则没有权值。
哈夫曼树的构造过程中,将权值较小的节点放在左子树,权值较大的节点放在右子树,这使得哈夫曼树的带权路径最短。
哈夫曼编码就是利用这种特性实现对数据进行压缩。
二、C语言实现构造哈夫曼树1. 定义结构体首先需要定义一个结构体来表示哈夫曼树中的节点。
结构体中包含了该节点的权值以及指向左右子节点的指针。
```typedef struct TreeNode {int weight;struct TreeNode *left;struct TreeNode *right;} TreeNode;2. 构造哈夫曼树接下来需要实现构造哈夫曼树的函数。
该函数接收一个数组作为输入,数组中存储了每个叶子节点的权值。
首先需要将数组中所有元素转化为TreeNode类型,并将它们存储在一个链表中。
```TreeNode *createTreeNodes(int weights[], int size) {TreeNode *nodes[size];for (int i = 0; i < size; i++) {nodes[i] = (TreeNode *)malloc(sizeof(TreeNode));nodes[i]->weight = weights[i];nodes[i]->left = NULL;nodes[i]->right = NULL;}return nodes;}```接下来,需要实现一个函数来找到权值最小的两个节点。
该函数接收一个链表作为输入,并返回该链表中权值最小的两个节点。
```void findMinNodes(TreeNode **nodes, int size, TreeNode**minNode1, TreeNode **minNode2) {*minNode1 = *minNode2 = NULL;for (int i = 0; i < size; i++) {if (*minNode1 == NULL || (*nodes)[i].weight <(*minNode1)->weight) {*minNode2 = *minNode1;*minNode1 = &(*nodes)[i];} else if (*minNode2 == NULL || (*nodes)[i].weight < (*minNode2)->weight) {*minNode2 = &(*nodes)[i];}}}```接下来,需要实现一个函数来构造哈夫曼树。
数据结构之哈夫曼编码和解码C源代码
玩转算法与数据结构之哈夫曼编码和解码—HIT2000鲁天伟二叉树的一个很重要的应用是生成哈夫曼树来完成哈夫曼编码和解码。
哈夫曼树:假设一个字符串中只有'A','B','C','D','E','F','G'这七个字符,这七个字符出现的权值(也就是出现次数)是3,5,7,6,5,9,8。
我们就以这个字符串作为样本,来进行字符编码,将字符映射成一串二进制码(比如’A’对应000,‘B’对应001),那么最终整个字符串将被编码成一长串二进制码。
我们生成哈夫曼树来进行编码,如下图1所展示就是哈夫曼树最终的模样。
哈夫曼树算法:使用字符数组{'A','B','C','D','E','F','G'},对就权值数组{3,5,7,6,5,9,8};1、我们先从权值数组左边开始,找到数组中未打过使用标记的最小数p和次小数q,以p+q作父结点,p作为左子结点,q作为右子结点。
原则是右子结点权值大于或等于左子结点权值。
把p和q的权值数组位置打标记已使用过,父结点p+q作为新的权值加入到权值数组尾部。
(此例中第一次执行p=3和q=5,对应字符‘A’和‘B’。
把这两个数相加得8,形成新的结点作为父结点。
3作为左子结点,5作为右子结点。
把3和5的权值数组位置打标记已使用过。
父结点权值8作为新的权值加入到权值数组尾部。
)2、重复步骤1,如果叶子结点有N个,那么进行N-1次合并,可以建成哈夫曼树。
图表 1 哈夫曼树编码算法:如上图1所示,所有的字符都出现在叶子结点的位置,从根结点开始遍历,查找每个叶子结点的字符,根到每个叶子结点只有一条路,从根开始向左走标0,向右走标1,根据查找路线,我们可以得出每个叶子结点字符的二进制编码串。
数据结构哈夫曼编码译码c语言
数据结构哈夫曼编码译码c语言哈夫曼编码是一种经典的数据压缩算法。
这种算法可以根据数据中出现频率最高的字符生成一个种类较少的编码表,然后用这个编码表来对数据进行编码,从而达到压缩数据的效果。
哈夫曼编码的核心是生成编码表,生成编码表的过程包括以下几个步骤:1. 统计字符出现频率。
遍历一遍数据,统计每个字符出现的次数。
2. 创建哈夫曼树。
将每个字符出现的次数作为权值,构造一棵哈夫曼树。
构造哈夫曼树需要用到一种优先队列。
3. 生成编码表。
对哈夫曼树进行遍历,当遇到一个叶子节点时,将它的路径上的所有节点转换成一个编码,这个编码就是该节点代表的字符的哈夫曼编码。
4. 对数据进行编码。
按照编码表,将原始数据中的每个字符都替换成对应的哈夫曼编码,得到压缩数据。
哈夫曼编码的解码操作相对简单,只需要根据编码表将每个哈夫曼编码转换成它代表的字符,再将这些字符拼接起来就可以得到原始数据。
以下是C语言实现哈夫曼编码和译码的例子:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_NODE 100typedef struct node {char data;int freq;int parent, lchild, rchild;} Node;int nodes_num;Node* nodes;void build_huffman_tree() {int i, j, min1, min2;for (i = 0; i < nodes_num - 1; i++) {min1 = min2 = -1;for (j = 0; j < nodes_num + i; j++) {if (nodes[j].parent == -1) {if (min1 == -1 || nodes[j].freq < nodes[min1].freq) {min2 = min1;min1 = j;} else if (min2 == -1 || nodes[j].freq < nodes[min2].freq) { min2 = j;}}}nodes[min1].parent = nodes_num + i;nodes[min2].parent = nodes_num + i;nodes[nodes_num + i].lchild = min1;nodes[nodes_num + i].rchild = min2;nodes[nodes_num + i].freq = nodes[min1].freq + nodes[min2].freq;}}nodes_num = 0;nodes = (Node*)malloc(MAX_NODE * sizeof(Node));for (i = 0; i < MAX_NODE; i++) {nodes[i].freq = nodes[i].parent = -1;nodes[i].lchild = nodes[i].rchild = -1;}build_huffman_tree();codes_num = 0;codes = (Code*)malloc(nodes_num * sizeof(Code));printf("src: %s\n", src);return 0;}```上述代码中,我们使用结构体来表示哈夫曼树的节点,其中包括该节点的权值(即字符出现的次数)、父节点、左右孩子节点等信息。
贪心算法哈夫曼编码c语言
贪心算法哈夫曼编码c语言哈夫曼编码的贪心算法可以分为以下几步:1. 读入需要编码的字符及其出现频率,并按照频率从小到大排序。
2. 构建哈夫曼树。
首先将所有字符看成只有一个节点的树,然后取出频率最小的两棵树,将它们合并成一棵树,这棵树的频率是两棵树的频率之和。
继续取出频率最小的两棵树,重复上述过程,直到只剩下一棵树为止,这就是哈夫曼树。
3. 对哈夫曼树进行编码。
从哈夫曼树的根节点开始,往左走为0,往右走为1,一直走到叶子节点,记录下这个叶子节点代表的字符的编码。
这就是哈夫曼编码。
以下是用C语言实现的贪心算法实现:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_N 256 // 假设字符集大小为256typedef struct node {char ch; // 字符int freq; // 频率struct node *left, *right; // 左右子节点} Node;// 建立一个新的节点Node* new_node(char ch, int freq) {Node *node = (Node*)malloc(sizeof(Node));node->ch = ch;node->freq = freq;node->left = node->right = NULL;return node;}// 在nodes数组中找寻最小的两个节点void find_min_two_nodes(Node **nodes, int size, int *min1, int *min2) {*min1 = *min2 = -1;for (int i = 0; i < size; i++) {if (nodes[i] == NULL) continue;if (*min1 == -1 || nodes[i]->freq < nodes[*min1]->freq) {*min2 = *min1;*min1 = i;} else if (*min2 == -1 || nodes[i]->freq < nodes[*min2]->freq) {*min2 = i;}}}// 构建哈夫曼树Node* build_huffman_tree(char *str, int *freq, int n) {Node *nodes[MAX_N];for (int i = 0; i < n; i++) {nodes[i] = new_node(str[i], freq[i]);}int size = n;while (size > 1) {int min1, min2;find_min_two_nodes(nodes, size, &min1, &min2);Node *node = new_node(0, nodes[min1]->freq +nodes[min2]->freq);node->left = nodes[min1];node->right = nodes[min2];nodes[min1] = node;nodes[min2] = NULL;size--;}return nodes[0];}// 递归生成哈夫曼编码void gen_huffman_code(Node *root, char *code, int depth, char **table) {if (root == NULL) return;if (root->left == NULL && root->right == NULL) {code[depth] = '\0';table[root->ch] = (char*)malloc((depth + 1) * sizeof(char)); strcpy(table[root->ch], code);return;}code[depth] = '0';gen_huffman_code(root->left, code, depth + 1, table);code[depth] = '1';gen_huffman_code(root->right, code, depth + 1, table); }// 哈夫曼编码char** huffman_code(char *str, int *freq, int n) {Node *root = build_huffman_tree(str, freq, n);char **table = (char**)malloc(MAX_N * sizeof(char*)); char code[MAX_N];gen_huffman_code(root, code, 0, table);return table;}int main() {char str[] = "ABACCABB";int freq[] = {2, 3, 1, 2, 1, 1, 1, 1};int n = strlen(str);char **table = huffman_code(str, freq, n);for (int i = 0; i < n; i++) {printf("char: %c, code: %s\n", str[i], table[str[i]]);}return 0;}```输出结果:```char: A, code: 11char: B, code: 0char: A, code: 11char: C, code: 100char: C, code: 100char: A, code: 11char: B, code: 1char: B, code: 01```这就是对字符串"ABACCABB"进行哈夫曼编码的结果。
数据结构实验哈夫曼树及哈夫曼编码c语言
数据结构实验报告:哈夫曼树及哈夫曼编码一、实验目的1. 理解哈夫曼树及哈夫曼编码的概念和原理;2. 掌握C语言中哈夫曼树及哈夫曼编码的实现方法;3. 分析和讨论哈夫曼编码在实际应用中的优势和不足。
二、实验内容和步骤1. 哈夫曼树的构建1.1 通过C语言实现哈夫曼树的构建算法;1.2 输入一组权值,按哈夫曼树构建规则生成哈夫曼树;1.3 输出生成的哈夫曼树结构,并进行可视化展示。
2. 哈夫曼编码的实现2.1 设计哈夫曼编码的实现算法;2.2 对指定字符集进行编码,生成哈夫曼编码表;2.3 对给定字符串进行哈夫曼编码,并输出编码结果。
三、实验过程及结果1. 哈夫曼树的构建在C语言中,通过定义结构体和递归算法实现了哈夫曼树的构建。
根据输入的权值,依次选择权值最小的两个节点构建新的父节点,直至构建完成整棵哈夫曼树。
通过调试和可视化展示,确认了程序正确实现了哈夫曼树的构建。
2. 哈夫曼编码的实现经过分析和设计,利用哈夫曼树的特点实现了哈夫曼编码的算法。
根据生成的哈夫曼树,递归地生成字符对应的哈夫曼编码,并输出编码结果。
对指定的字符串进行了编码测试,验证了哈夫曼编码的正确性和有效性。
四、实验结果分析1. 哈夫曼编码在数据传输和存储中具有较高的压缩效率和可靠性,能够有效减少数据传输量和存储空间;2. 哈夫曼树及哈夫曼编码在通信领域、数据压缩和加密等方面有着广泛的应用和重要意义;3. 在实际应用中,哈夫曼编码的构建和解码算法需要较大的时间和空间复杂度,对于大规模数据的处理存在一定的局限性。
五、实验总结通过本次实验,深入理解了哈夫曼树及哈夫曼编码的理论知识,并掌握了C语言中实现哈夫曼树及哈夫曼编码的方法。
对哈夫曼编码在实际应用中的优势和局限性有了更深入的认识,这对今后的学习和工作有着积极的意义。
六、参考文献1. 《数据结构(C语言版)》,严蔚敏赵现军著,清华大学出版社,2012年;2. 《算法导论》,Thomas H. Cormen 等著,机械工业出版社,2006年。
用c++写哈夫曼编码
用c++写哈夫曼编码以下是使用C++实现哈夫曼编码的示例代码:c复制代码#include<iostream>#include<queue>#include<string>#include<vector>using namespace std;struct TreeNode {char data;int freq;TreeNode *left, *right;TreeNode(char data, int freq) : data(data), freq(freq), left(NULL), right(NULL) {}};struct cmp {bool operator()(const TreeNode *a, const TreeNode *b) {return a->freq > b->freq;}};void printCodes(TreeNode *root, string code) {if (root == NULL) {return;}if (root->left == NULL && root->right == NULL) {cout << root->data << ": " << code << endl;return;}printCodes(root->left, code + "0");printCodes(root->right, code + "1");}void buildHuffmanTree(const vector<char>& data, const vector<int>& freq) { priority_queue<TreeNode*, vector<TreeNode*>, cmp> pq;for (int i = 0; i < data.size(); i++) {pq.push(new TreeNode(data[i], freq[i]));}while (pq.size() > 1) {TreeNode *left = pq.top();pq.pop();TreeNode *right = pq.top();pq.pop();TreeNode *top = new TreeNode('$', left->freq + right->freq);top->left = left;top->right = right;pq.push(top);}TreeNode *root = pq.top();pq.pop();printCodes(root, "");}int main() {vector<char> data = {'a', 'b', 'c', 'd', 'e', 'f'};vector<int> freq = {5, 9, 12, 13, 16, 45};buildHuffmanTree(data, freq);return0;}在这个示例中,我们首先定义了一个结构体TreeNode,表示哈夫曼树的节点。
哈夫曼编码的C语言实现
哈夫曼编码的C语言实现一、大致思路输入信源符号的概率,构造哈夫曼树,从叶子结点到根结点进行编码二、编码实现#include <stdio.h>#define n 7 //leaf number#define m 2*n-1 //all numbertypedef struct{char ch;double weight;int left;int right;int parent;}Node;typedef struct{char ch;int codeis[50];int start;}Code;void HuffmanTree (Node node[],int number){int i,j,x1=0,x2=0;double m1,m2;for(i=0;i<n-1;i++){ //loop n-1m1=m2=1; //least probability p<1//m1 最小 m2第二小for(j=0;j<n+i;j++){if(node[j].weight <m1 && node[j].parent ==-1){m2=m1;x2=x1;m1=node[j].weight;x1=j;} //是最小的else if(node[j].weight <m2 &&node[j].parent ==-1){m2=node[j].weight;x2=j;}} //找结点node[x1].parent = number+i;node[x2].parent = number+i;node[number+i].weight = node[x1].weight + node[x2].weight;node[number+i].left = x1;node[number+i].right = x2;}//end for}int main(int argc, const char * argv[]) {double x[n]={0};printf("请输入%d个符号的概率",n);int i;for(i=0;i<n;i++){scanf("%lf",&x[i]);}Node node[2*n-1]; // 2*len-1 is the number of all nodefor(i=0;i<2*n-1;i++){node[i].weight = 0;node[i].left = -1;node[i].right = -1;node[i].parent = -1;} //initializefor(i=0;i<n;i++){node[i].weight=x[i];}Code code[n],tempcode; //save the code of leafHuffmanTree(node,n); //创建好了哈夫曼树//编码int p,c,j=0;for(i=0;i<n;i++){c=i;tempcode.start = n-1;p=node[c].parent;while(p!=-1){if(node[p].left == c)tempcode.codeis[tempcode.start] = 1; elsetempcode.codeis[tempcode.start] = 0; tempcode.start--;c=p;p=node[c].parent;} //end whilefor(j=tempcode.start+1;j<n;j++){code[i].codeis[j]=tempcode.codeis[j];}//保存下载刚才的结果code[i].start = tempcode.start;} //end forfor (i=0;i<n;i++){for (j=code[i].start+1;j<n;j++){printf("%d",code[i].codeis[j]);}printf("\n");}getchar();return 0;}三、总结1.创建了哈夫曼树,n是叶子结点数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
beforeptr=beforeptr->next; /*后移*/
}
if(ptr&&ptr->ch==node->ch) {/*如果链表中某结点的字符与新结点的字符相同*/
/*将该结点的权加一*/
ptr->weight=ptr->weight+1;
char0_1[j]='\0';
printf("没有与最后的几个0、1序列:%s相匹配的字符!\n",char0_1);
return;
}
}
free(char0_1);
}
/*文件*/
inchange()
{
FILE *fp;
char ch;
if((fp=fopen("e10_1.c","rt"))==NULL)
ptr=tree;
index=0;
}
if(ptr->lchild->mark==1&&ptr->rchild->mark==1)
{
ptr->mark=1;
ptr=tree;
index=0;
}
}
}
printf("\n");
free(code);
}
printf("霍夫曼编码-----相应字符\n\n");
for(j=0,ptr=tree;code[i]!='\0'&&ptr->lchild&&ptr->rchild;j=0,ptr=tree) {
for(j=0;code[i]!='\0'&&ptr->lchild&&ptr->rchild;j++,i++) {
else {
while(ptr->lchild&&ptr->rchild&&ptr->mark==0) {
while(ptr->lchild&&ptr->lchild->mark==0) {
code[index++]='0';
ptr=ptr->lchild;
if(!ptr->lchild&&!ptr->rchild) {
node=(linktree)malloc(sizeof(Hftree)); /*新申请结点node*/
if(!node)return NULL;
node->next=NULL;
node->parent=NULL;
node->lchild=NULL;
node->rchild=NULL; /*置空*/
{
printf("Cannot open file strike any key exit!");
getch();
exit(1);
}
ch=fgetc(fp);
while (ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);
ptr=tree;
index=0;
}
}
if(ptr->rchild&&ptr->rchild->mark==0) {
ptr=ptr->rchild;
code[index++]='1';
}
if(!ptr->lchild&&!ptr->rchild) {
ptr->mark=1;
struct Huffmantree *parent,*lchild,*rchild,*next;
}Hftree,*linktree;
/*整理输入的字符串,合并相同的项,并求出每个字符在数组中出现的次数 */
linktree tidycharacter(char character[])
code=(char *)malloc(10*sizeof(char));/*此数组用于统计霍夫曼编码*/
printf("字符以及它的相应权数---------霍夫曼编码\n\n");
if(ptr==NULL) {
printf("霍夫曼树是空的!\n");
exit(0);
}
/*解码 */
void decode(linktree tree,char code[])
{
int i=0,j=0;
char *char0_1;
linktree ptr=tree;
char0_1=(char *)malloc(10*sizeof(char));/*此数组用于统计输入的0、1序列*/
{
linktree p,q,newnode,beforep;
for(p=tree->next,q=p->next;p!=NULL&&q!=NULL;p=tree->next,q=p->next) {
tree->next=q->next;
q->next=NULL;
p->next=NULL;
ptr->mark=1;
code[index]='\0';
printf("\tw[%c]=%d\t\t\t",ptr->ch,ptr->weight);
for(index=0;code[index]!='\0';index++)
printf("%c",code[index]);
printf("\n");
newnode->next=beforep->next;
beforep->next=newnode;
}
else {
while(p!=NULL&&p->weight<newnode->weight) {
p=p->next;
beforep=beforep->next;
}
newnode->next=beforep->next;
if(!tree)return NULL;
tree->next=NULL; /* 头结点为空,且后续结点为空*/
for(i=0;character[i]!='\0'&&character[i]!='\n';i++) { /*遍历直到字符串结束为止*/
ptr=tree;
beforeptr=tree;
if(code[i]=='0') {
ptr=ptr->lchild;
char0_1[j]='0';
}
if(code[i]=='1') {
ptr=ptr->rchild;
char0_1[j]='1';
}
}
if(!ptr->lchild&&!ptr->rchild) {
free(node); /*释放node结点的存储空间*/
}
else {/*新结点与表中结点不相同,将新结点插入链表后*/
node->next=beforeptr->next;
beforeptr->next=node; /*node连接在beforeptr之后*/
}
}
}
{
int i=0;
linktree tree,ptr,beforeptr,node; /*链式 ,tree为头结点,beforeptr为ptr的前一结点,node为新申请的结点*/
tree=(linktree)malloc(sizeof(Hftree));/*创建单链表的头结点*/
}
}
void main()
{ int n;
char character[MAXLEN],code[MAXLEN];
beforep->next=newnode;
}
}
return (tree->next);
}
/*对霍夫曼树进行编码 */
void Huffmancoding(linktree tree)
{
int index=0;
char *code;
linktree ptr=tree;
newnode->rchild=q;
p->parent=newnode;
q->parent=newnode;
newnode->weight=p->weight+q->weight;
p=tree->next;
beforep=tree;
if(p!=NULL&&p->weight>=newnode->weight) {/*将新结点插入原链表的相应位置*/
#include <conio.h>