霍夫曼编码的C语言实现
霍夫曼编码设计实验报告

一、实验目的1. 理解霍夫曼编码的基本原理和算法流程。
2. 掌握霍夫曼编码的构建过程和编码方法。
3. 通过实验验证霍夫曼编码在数据压缩方面的效果。
4. 提高编程能力和数据结构应用能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验原理霍夫曼编码是一种基于字符出现频率进行编码的数据压缩方法。
其基本原理如下:1. 对字符进行统计,得到每个字符出现的频率。
2. 根据频率对字符进行排序,频率高的字符排在前面。
3. 构建霍夫曼树,将频率高的字符放在树的左侧,频率低的字符放在树的右侧。
4. 从树根到叶子节点,为每个字符分配一个二进制编码,频率高的字符用较短的编码表示,频率低的字符用较长的编码表示。
四、实验步骤1. 定义一个结构体HuffmanNode,用于存储字符及其频率。
2. 实现一个函数用于统计字符频率。
3. 实现一个函数用于构建霍夫曼树。
4. 实现一个函数用于生成霍夫曼编码。
5. 实现一个函数用于解码霍夫曼编码。
6. 编写主函数,进行实验验证。
五、实验过程1. 定义结构体HuffmanNode,用于存储字符及其频率。
```cppstruct HuffmanNode {char ch;int weight;HuffmanNode lchild, rchild;};```2. 实现一个函数用于统计字符频率。
```cppvoid StatFrequency(char str, int freq) {int length = strlen(str);for (int i = 0; i < 256; ++i) {freq[i] = 0;}for (int i = 0; i < length; ++i) {freq[(int)str[i]]++;}}```3. 实现一个函数用于构建霍夫曼树。
```cppHuffmanNode CreateHuffmanTree(int freq, int length) {HuffmanNode nodes = new HuffmanNode[length + 1];for (int i = 0; i < length; ++i) {nodes[i].ch = 'a' + i;nodes[i].weight = freq[i];nodes[i].lchild = nullptr;nodes[i].rchild = nullptr;}for (int i = length; i < length + 1; ++i) {nodes[i].ch = '\0';nodes[i].weight = 0;nodes[i].lchild = nullptr;nodes[i].rchild = nullptr;}for (int i = 0; i < length - 1; ++i) {HuffmanNode minNode1 = &nodes[0];HuffmanNode minNode2 = &nodes[1];for (int j = 0; j < length + 1; ++j) {if (nodes[j].weight < minNode1->weight) {minNode2 = minNode1;minNode1 = &nodes[j];} else if (nodes[j].weight < minNode2->weight && nodes[j].weight > minNode1->weight) {minNode2 = &nodes[j];}}nodes[i].weight = minNode1->weight + minNode2->weight;nodes[i].lchild = minNode1;nodes[i].rchild = minNode2;minNode1->parent = &nodes[i];minNode2->parent = &nodes[i];}return &nodes[length - 1];}```4. 实现一个函数用于生成霍夫曼编码。
霍夫曼编码原理c语言实现

霍夫曼编码原理c语言实现
霍夫曼编码是一种常用的数据压缩算法,它通过根据字符出现的频率来构建不等长的编码,以实现对数据的高效压缩。
在C语言中,可以通过以下步骤来实现霍夫曼编码的原理:
1. 首先,需要定义一个结构体来表示霍夫曼树的节点,包括字符、频率和左右子节点等信息。
c.
struct Node {。
char data;
int freq;
struct Node left, right;
};
2. 接下来,需要实现霍夫曼树的构建算法,可以使用优先队列(最小堆)来实现。
首先创建一个包含所有字符频率的最小堆,然
后依次取出两个最小频率的节点,合并成一个新的节点,再将新节
点插入到最小堆中。
重复这个过程,直到最小堆中只剩下一个节点,即霍夫曼树的根节点。
3. 构建霍夫曼编码表,可以使用递归的方法遍历霍夫曼树,对
每个字符生成对应的霍夫曼编码。
4. 最后,使用生成的霍夫曼编码表对输入的数据进行编码和解
码操作。
编码时,将输入的字符逐个转换为对应的霍夫曼编码;解
码时,根据霍夫曼树的结构和编码表,将霍夫曼编码逐个解析为原
始字符。
以上是简要的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语言模板

一、需求分析目前,进行快速远距离通信的主要手段是电报,即将需传送的文字转化成由二级制的字符组成的字符串。
例如,假设需传送的电文为“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); //译码三、 详细设计(一)、建立哈夫曼树a b c d1 2 3 4 5 * * * 6 7 a b * c *ab*c *d * 序号: 字符: 权值: 1 2 3 4 3 6 10 a b * 1 2 1 2 3 3 1 2 3 3 6 4 103 6 图3-1 图3-2 图3-3(二)、对哈夫曼树进行编码 主要代码实现:for(c=i,f=p[i].parent;f!=0;c=f,f=p[f].parent) { if(p[f].lchild==c) //左孩子编码为'0'{ cd[--start]='0'; } else //右孩子编码为'1'{ cd[--start]='1'; } }(三)、输出对应字符的码字符 编码 a 110 b 111 c 10 d(四)、译码过程 主要代码实现:if(strcmp(a,hc[i])==0) //比较两个字符串是否相等,相等则输出0 { for(c=2*n-1,j=0;a[j]!='\0';j++) //从根出发,按字符'0'或'1'确定找左孩子或右孩子 { if(a[j]=='0') //左孩子 {c=p[c].lchild;}else {c=p[c].rchild; //右孩子 }}ab* c* d*1 1 0 1 0 图3-4表3-1从叶子到根逆向求编码a b*c *d *0 1 1 1 从跟到叶子顺向求字符 图3-5四、 调试分析(一)、数字的输入判断(二)、字母的输入判断(三)、程序是否继续进行的判断五、 用户手册(一)、首先根据提示输入初始化数据,提示输入一个数字,请输入一个数a ,0<a<9999;提示输入一个字母,则请输入一个字母(a~z)或者(A~Z)中的一个字符;请勿在输入一个数字后再输入一个字符,或者在输入一个字符后再输入一个数字。
C++实现哈夫曼编码完整代码

C++实现哈夫曼编码完整代码#include <iostream>#include <queue>#include <vector>#include <map>#include <string>using namespace std;class Node {public:char c; //表示字符int frequency; //表示该字符出现的次数或频率Node *left;Node *right;Node(char _c, int f, Node *l = NULL, Node *r = NULL):c(_c), frequency(f), left(l), right(r) { }bool operator<(const Node &node) const { //重载<运算法以至于在加入优先队列的时候决定如何处理结点位置return frequency > node.frequency;}};void initNode(priority_queue<Node> &q, int nodeNum) {char c;int frequency;for (int i = 0; i < nodeNum; i++) {cout << "输入字符和结点出现的次数: ";cin >> c >> frequency;Node node(c, frequency);q.push(node);}}void showNode(priority_queue<Node> q) {while (!q.empty()) {Node node = q.top(); q.pop();cout << node.c << ", " << node.frequency << endl;}}//构造哈夫曼树void huffmanTree(priority_queue<Node> &q) {while (q.size() != 1) {Node *left = new Node(q.top()); q.pop();Node *right = new Node(q.top()); q.pop();Node node('R', left->frequency + right->frequency, left, right);q.push(node);}}// 打印哈夫曼编码void huffmanCode(Node *root, string &prefix, map<char, string> &result) { string m_prefix = prefix;if (root->left == NULL)return;//处理左子树prefix += "0";//如果是叶子结点则输出,否则递归打印左子树if (root->left->left == NULL)result[root->left->c] = prefix;//cout << root->left->c << ": " << prefix << endl;elsehuffmanCode(root->left, prefix, result);//还原原来的路径,回溯prefix = m_prefix;//处理右子树prefix += "1";//如果是叶子结点,则输出, 否则递归打印右子树if (root->right->right == NULL)result[root->right->c] = prefix;//cout << root->right->c << ": " << prefix << endl;elsehuffmanCode(root->right, prefix, result);}void testResult(map<char, string> result) {//迭代map容器map<char, string>::const_iterator it = result.begin(); while (it != result.end()) {cout << it->first << ": " << it->second << endl;++it;}}int main() {priority_queue<Node> q;int nodeNum;//初始化字符信息cout << "请输入结点个数: ";cin >> nodeNum;initNode(q, nodeNum);//showNode(q);//构造哈夫曼树huffmanTree(q);//构造哈夫曼编码Node root = q.top();string prefix = "";map<char, string> result;huffmanCode(&root, prefix, result);//检验结果是否正确testResult(result);return 0;}。
信息论实验哈夫曼编码c语言

信息论实验哈夫曼编码c语言以下是使用C语言实现哈夫曼编码的示例代码:```cinclude <>include <>include <>define MAX_TREE_HT 100struct MinHeapNode {char data;unsigned freq;struct MinHeapNode left, right;};struct MinHeap {unsigned size;unsigned capacity;struct MinHeapNode array;};struct MinHeapNode newNode(char data, unsigned freq) {struct MinHeapNode temp = (structMinHeapNode)malloc(sizeof(struct MinHeapNode));temp->left = temp->right = NULL;temp->data = data;temp->freq = freq;return temp;}struct MinHeap createMinHeap(unsigned capacity) {struct MinHeap minHeap = (struct MinHeap)malloc(sizeof(struct MinHeap));minHeap->size = 0;minHeap->capacity = capacity;minHeap->array = (struct MinHeapNode)malloc(minHeap->capacity sizeof(struct MinHeapNode));return minHeap;}void swapMinHeapNode(struct MinHeapNode a, struct MinHeapNode b) {struct MinHeapNode t = a;a = b;b = t;}void minHeapify(struct MinHeap minHeap, int idx) {int smallest = idx;int left = 2 idx + 1;int right = 2 idx + 2;if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq) {smallest = left;}if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq) {smallest = right;}if (smallest != idx) {swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]);minHeapify(minHeap, smallest);}}int isSizeOne(struct MinHeap minHeap) {return (minHeap->size == 1);}void insertMinHeap(struct MinHeap minHeap, struct MinHeapNode minHeapNode) {minHeap->size++;int i = minHeap->size - 1;while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {minHeap->array[i] = minHeap->array[(i - 1) / 2];i = (i - 1) / 2;}minHeap->array[i] = minHeapNode;}struct MinHeapNode extractMin(struct MinHeap minHeap) { struct MinHeapNode root = minHeap->array[0];minHeap->array[0] = minHeap->array[minHeap->size - 1]; --minHeap->size;minHeapify(minHeap, 0);return root;}void buildMinHeap(struct MinHeap minHeap) {int n = minHeap->size - 1;int i;for (i = (n - 1) / 2; i >= 0; --i) {minHeapify(minHeap, i);}}void printArr(int arr[], int n) {int i;for (i = 0; i < n; ++i) {printf("%d", arr[i]);if (i < n - 1) {printf(" ");} else {printf("\n");}}}int isLeaf(struct MinHeapNode root) {return !(root->left) && !(root->right);}void printCodes(struct MinHeapNode root, int arr[], int top) {if (root->left) {arr[top] = 0; // left branch -> 0 in binary tree representation.! So first bit of code for root will be '0'! So, '0' is the prefix for all left branches! Therefore, '。
霍夫曼编码的实验报告(3篇)

第1篇一、实验目的1. 理解霍夫曼编码的基本原理和实现方法。
2. 掌握霍夫曼编码在数据压缩中的应用。
3. 通过实验,加深对数据压缩技术的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 20194. 数据源:文本文件三、实验原理霍夫曼编码是一种常用的数据压缩算法,适用于无损数据压缩。
它通过使用变长编码表对数据进行编码,频率高的数据项使用短编码,频率低的数据项使用长编码。
霍夫曼编码的核心是构建一棵霍夫曼树,该树是一种最优二叉树,用于表示编码规则。
霍夫曼编码的步骤如下:1. 统计数据源中每个字符的出现频率。
2. 根据字符频率构建一棵最优二叉树,频率高的字符位于树的上层,频率低的字符位于树下层。
3. 根据最优二叉树生成编码规则,频率高的字符分配较短的编码,频率低的字符分配较长的编码。
4. 使用编码规则对数据进行编码,生成压缩后的数据。
5. 在解码过程中,根据编码规则恢复原始数据。
四、实验步骤1. 读取文本文件,统计每个字符的出现频率。
2. 根据字符频率构建最优二叉树。
3. 根据最优二叉树生成编码规则。
4. 使用编码规则对数据进行编码,生成压缩后的数据。
5. 将压缩后的数据写入文件。
6. 读取压缩后的数据,根据编码规则进行解码,恢复原始数据。
7. 比较原始数据和恢复后的数据,验证压缩和解码的正确性。
五、实验结果与分析1. 实验数据实验中,我们使用了一个包含10000个字符的文本文件作为数据源。
在统计字符频率时,我们发现字符“e”的出现频率最高,为2621次,而字符“z”的出现频率最低,为4次。
2. 实验结果根据实验数据,我们构建了最优二叉树,并生成了编码规则。
使用编码规则对数据源进行编码,压缩后的数据长度为7800个字符。
将压缩后的数据写入文件,文件大小为78KB。
接下来,我们读取压缩后的数据,根据编码规则进行解码,恢复原始数据。
比较原始数据和恢复后的数据,发现两者完全一致,验证了压缩和解码的正确性。
哈夫曼编码的原理及C++实现

哈夫曼编码的原理及C++实现哈夫曼编码(Huffman Coding)是一种非常经典的编码方式,实现起来也很简单,在实际的笔试面试过程中有可能会遇到,这里介绍一下它的原理和一个使用优先队列的实现版本。
一编码原理哈夫曼编码是一种可变长的编码,它依据字符出现的概率来决定字符编码的长度,使得出现概率大的字符编码长度短,出现概率小的字符的编码长度长,于是可以减少整体的编码的长度。
哈弗曼编码时首先根据待编码的文本统计出每个字符出现的概率,组成初始的节点。
然后每次取出概率最小的两个节点,新建一个节点,使得新建节点的左右儿子为选取的两个节点,并且其概率是两个节点概率之和,把新建的节点再放进所有节点中重新选择最小的两个节点。
重复此过程直到只剩一个节点,这个就是哈夫曼树的根节点。
以下以字符串"aaaaaabbbbccddd"为例进行说明,为了方便,以字符出现的频数来代替频率(实际中通常使用的是频率,二者效果上是一样的),经过统计,可以知道每个字符出现的频数为a b c d6 4 2 3具体建树过程如下:(1)首先节点权值为6、4、2、3,选择最小的2和3,组成一个根节点为5的组合节点。
(2)当前节点权值为6、4、5,选择最小的4和5,组成一个根节点为9的组合节点。
(3)当前节点权值为6、9,选择最小的6和9,组成一个根节点为15的组合节点。
(4)当前节点权值为15,只有一个节点,哈夫曼树建立完成。
图示如下:要从哈夫曼树得到每个字符的编码,只要在哈夫曼树中从根节点遍历到该字符节点,每次向左走时加一个0,向右走时加一个1,最终得到的字符串即为该字符的编码字符串。
如从上图可以看到,a的编码为0,b的编码为10,c的编码为110,d的编码为111。
当遇到一个新的字符串时,比如说"abcd",要对其编码,只需要把其中的每个字符相应地替换成其编码字符串即可。
当已知一个编码后的字符串,比如说"010110111",要对其解码时,只需从左到右依次扫描该编码串,当读到的串在哈弗曼编码表里有对应的字符时即解码为该字符,然后继续扫描。
简单的曼彻斯特编码的C语言实现

简单的曼彻斯特编码的C语言实现曼彻斯特编码是减小信号交流分量,实现固定信号占空比的基本方法。
用C语言实现如下:#include <stdio.h>#define uint8_t unsigned char#define uint16_t int#define BOOL int#define TRUE 1#define FALSE 0BOOL app_ManchesterEncode(uint8_t *indata,uint8_t *outdata,uint16_t inlength);BOOL app_ManchesterDecode(uint8_t *indata,uint8_t *outdata,uint16_t inlength);uint8_t indata[10]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0x43,0xb8};uint8_t middata[20];uint8_t outdata[10];uint16_t inlength;int main(){int length=10;int i=0;app_ManchesterEncode(indata,middata,length);if(app_ManchesterDecode(middata,outdata,length*2)==FALSE)printf("decode failed!\n");printf("in:");for(i=0;i<length;i++)printf(" %2.2x",indata[i]);printf("\n");printf("mid:");for(i=0;i<length*2;i++)printf(" %2.2x",middata[i]);printf("\n");printf("out:");for(i=0;i<length;i++)printf(" %2.2x",outdata[i]);printf("\n");}BOOL app_ManchesterEncode(uint8_t *indata,uint8_t *outdata,uint16_t inlength) {uint16_t i=0;uint8_t j=0;for(i=0;i<inlength;i++){outdata[2*i]=0;outdata[2*i+1]=0;for(j=0;j<8;j++)if(j<4)outdata[2*i+1]|=(((indata[i]>>j)&0x01)?2:1)<<j*2;elseoutdata[2*i]|=(((indata[i]>>j)&0x01)?2:1)<<(j*2-8);}return TRUE;}BOOL app_ManchesterDecode(uint8_t *indata,uint8_t *outdata,uint16_t inlength) {uint16_t i=0;uint8_t j=0;for(i=0;i<inlength/2;i++){outdata[i]=0;for(j=0;j<8;j++){if(j<4){if((indata[2*i+1]>>(j*2)&0x03)==0x01);else if((indata[2*i+1]>>(j*2)&0x03)==0x02)outdata[i]|=0x01<<j;else{printf("at i=%d j=%d data:%2.2x ",i,j,indata[2*i+1]&0x03);return FALSE;}}else{if((indata[2*i]>>(j*2-8)&0x03)==0x01);else if((indata[2*i]>>(j*2-8)&0x03)==0x02)outdata[i]|=0x01<<j;else{printf("at i=%d j=%d\n",i,j);return FALSE;}}}}return TRUE;}。
哈夫曼编码详解(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;```上述的示例代码实现了一个简单的哈夫曼编码和解码过程。
霍夫曼编码c语言

霍夫曼编码c语言霍夫曼编码是一种用于数据压缩的编码技术,它通过重新组织数据中的符号来减少传输或存储数据所需的比特数。
在C语言中实现霍夫曼编码需要掌握数据结构、算法和编码理论的基础知识。
一、霍夫曼编码原理霍夫曼编码的基本原理是利用符号出现的频率来构建一个最优的编码方案,使得编码后的比特率最小。
在霍夫曼图中,每个符号对应一个唯一的路径,路径上的节点表示该符号可能出现的概率。
通过选择概率较大的路径,可以获得较短的编码,从而实现数据压缩。
二、C语言实现霍夫曼编码以下是一个简单的C语言实现霍夫曼编码的示例代码:```c#include<stdio.h>#include<stdlib.h>#include<stdbool.h>//定义霍夫曼树节点结构体typedefstructNode{charsymbol;//符号structNode*left;//左子节点structNode*right;//右子节点intfrequency;//符号频率}Node;//构建霍夫曼树函数Node*buildHuffmanTree(intfrequencies[],intn){//合并相同频率的节点for(inti=0;i<n-1;i++){for(intj=i+1;j<n;j++){if(frequencies[i]==frequencies[j]){ Node*temp=frequencies[i]; frequencies[i]=frequencies[j]; frequencies[j]=temp;mergeNodes(frequencies,i,j);}}}//构建霍夫曼树Node*root=NULL;for(inti=0;i<n;i++){if(root==NULL){root=frequencies[i];}else{Node*child=frequencies[i];child->left=root;root->right=child;root=child;}}returnroot;}//合并两个节点的函数voidmergeNodes(intfrequencies[],inti,intj){frequencies[i]=frequencies[j];//合并节点频率frequencies[j]=NULL;//移除多余节点}//输出霍夫曼编码函数voidprintCodes(Node*root,char*codes[],intindex){if(root==NULL){//如果节点为空,输出编码为空字符串printf("%s",codes[index]);return;}elseif(root->left!=NULL){//如果节点左子节点不为空,输出左子节点的编码作为前缀printCodes(root->left,codes,index*2+1);}elseif(root->right!=NULL){//如果节点右子节点不为空,输出右子节点的编码作为前缀(可用作解码的辅助信息)printCodes(root->right,codes,index*2+2);}else{//如果节点为叶子节点,输出节点的符号作为编码的前缀(去掉重复前缀)并输出当前编码的长度(作为该符号的出现次数)intfreq=root->frequency;//当前符号频率(去掉重复前缀后的频率)while(codes[index]!='\0'){//将前缀放入已使用的字符串数组中以供其他叶子节点使用,重复前缀使用最少的次数(去除重复)并输出当前编码长度和符号本身作为输出结果index--;//指针向后移动一位,直到指针指向'\0'字符为止(已使用的字符串数组)或遇到NULL字符为止(编码数组结束)并返回编码长度和符号本身作为输出结果供其他叶子节点使用和参考。
哈夫曼编解码完整c程序代码

字符
A
B
C
D
E
F
G
H
I
J
K
Lห้องสมุดไป่ตู้
M
频度
186
64
13
22
32
103
21
15
47
57
1
5
32
20
字符
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
频度
57
63
15
1
48
51
80
23
case'Q':break;
}
}while(state!='Q');
}
void menu() //显示菜单函数
{
std::cout<<"===========HuffmanCoding===========\n";
std::cout<<"input \t\t do\n";
std::cout<<"I \t\tInit_HUffTree\n"; //初始化huffmantree
void decoding(int n);
void coding(int n);
void main()
{
int n=0;
menu();
Huff HT;
char state;
do
{
C语言数据压缩与解压缩压缩算法和文件格式

C语言数据压缩与解压缩压缩算法和文件格式C语言数据压缩与解压缩在计算机编程领域中,数据压缩是一项重要的技术,可以将数据以更高效的方式存储和传输。
C语言是一种广泛应用于程序开发的编程语言,具有高效执行和灵活性的特点,因此常被用于开发数据压缩和解压缩算法。
本文将介绍C语言中常用的数据压缩和解压缩方法,以及相关的文件格式。
一、数据压缩算法数据压缩算法是用于减小数据所占用的存储空间或传输带宽的方法。
在C语言中,常用的数据压缩算法包括:1. 霍夫曼编码(Huffman Coding):霍夫曼编码是一种基于字符频率的无损数据压缩算法。
它通过构建最优二叉树,将频率较高的字符用较短的编码表示,从而实现压缩。
在C语言中,可以使用哈希表或二叉树实现霍夫曼编码。
2. Lempel-Ziv-Welch压缩算法(LZW):LZW是一种无损数据压缩算法,常用于压缩文本数据。
它通过建立字典表,将连续出现的字符序列映射为一个短的编码,从而减小存储空间。
在C语言中,可以使用哈希表或树结构实现LZW算法。
3. Run-Length Encoding(RLE):RLE是一种基于连续重复数据的无损压缩算法。
它通过记录重复数据的起始位置和重复次数,将连续重复的数据替换成一个标记和计数值,从而实现压缩。
C语言中实现RLE算法相对简单,只需遍历数据并统计重复次数即可。
4. Deflate压缩算法:Deflate是一种广泛应用于各种文件压缩格式(如ZIP和GZIP)的无损压缩算法。
它结合了LZ77算法和霍夫曼编码,能够在较高的压缩比和较快的压缩速度之间取得平衡。
C语言中可以使用相关的开源库实现Deflate算法。
二、数据解压缩方法数据解压缩是将压缩后的数据还原为原始数据的过程。
在C语言中,实现数据解压缩的方法与对应的压缩算法相对应,具体包括:1. 霍夫曼编码的解码:对于使用霍夫曼编码进行压缩的数据,需要使用相应的解码算法来还原原始数据。
解码过程涉及对霍夫曼树的遍历,根据编码找到对应的字符,从而实现解压缩。
贪心算法哈夫曼编码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"进行哈夫曼编码的结果。
信源编码--------霍夫曼编码

实验二 信源编码--------霍夫曼编码1. 掌握信息熵的定义、性质和计算;2. 掌握平均码字长度和编码效率的计算;3. 掌握霍夫曼编码的原理;4. 熟练掌握二进制霍夫曼码的编码步骤;5. 正确使用C 语言实现霍夫曼编码。
二、实验内容1. 熟练画出霍夫曼编码图,正确求出字符串的二进制霍夫曼编码;2. 用C 语言正确编程,实现霍夫曼编码、解码,并在Visual C++环境中验证。
三、 实验原理1. 霍夫曼编码的基本原理按照概率大小顺序排列信源符号,并设法按逆顺序分配码字字长,使编码的码字为可辨识的。
2. 平均码长:L=∑p(s i )*l i (单位为:码符号/信源符号)其中,p(s i )为信源s i 在q 个信源中出现的概率,l i 为信源s i 的二进制霍夫曼编码。
3. 信息熵:H(S)=- ∑p(s i ) *log 2 p(s i ) (单位为:比特/信源符号)其中,p(s i )为信源s i 在q 个信源中出现的概率。
4. 编码效率:η= H(S)/ L其中,H(S)为信息熵,L 为平均码长。
四、 实验步骤:1. 将q 个信源符号按概率分布的大小,以递减次序排列起来,设)()()(21q x p x p x p ≥≥≥2. 用“0”和“1”码符号分别代表概率最小的两个信源符号,并将这两个概率最小的符号合并成一个符号,合并的符号概率为两个符号概率之和,从而得到只包含q-1个符号的新信源,称为缩减信源。
3. 把缩减信源的符号仍旧按概率大小以递减次序排列,再将其概率最小的两个信源符号分别用“0”和“1”表示,并将其合并成一个符号,概率为两符号概率之和,这样又形成了 q – 2 个符号的缩减信源。
4. 依此继续下去,直至信源只剩下两个符号为止。
将这最后两个信源符号分别用“0”和“1”表示。
5. 然后从最后一级缩减信源开始,向前返回,就得出各信源符号所对应的码符号序列,即对应的码字。
/****************** 霍夫曼编码 **********************///2010-3-31:注释//程序共有8处需要补充#include<stdio.h>#include<string.h>#include<math.h>#define n 100#define m 2*n-1// 码结点的存储结构typedef struct{char ch;char bits[9];int len;}CodeNode;typedef CodeNode HuffmanCode[n+1];// 树结点的存储结构typedef struct{int weight;int lchild,rchild,parent;}HTNode;typedef HTNode HuffmanTree[m+1];int num;// 挑选权值最小的两个结点void select(HuffmanTree HT, int k, int &s1, int &s2){int i,j;int minl=32767;for(i=1;i<=k;i++)if(HT[i].weight<minl&&HT[i].parent==0){j=i;minl=HT[i].weight;}s1=j;minl=32767;for(i=1;i<=k;i++)if(HT[i].weight<minl&&HT[i].parent==0&&i!=s1){j=i;minl=HT[i].weight;}s2=j;}// 统计输入字符串st中出现的字符种类和各个字符在该字符串中出现的次数,// 出现的字符存放在str数组中,各个字符在该字符串中出现的次数存放在// cnt数组中,返回字符串st中字符种类数。
c 二进制压缩算法

c 二进制压缩算法
C语言中常用的二进制压缩算法有很多种,其中比较常见的算法有霍夫曼编码、LZ77、LZW等。
这些算法都可以在C语言中实现。
1. 霍夫曼编码(Huffman Coding)是一种无损压缩算法,它通过构建一个最优前缀编码树来实现压缩。
在C语言中,可以使用数组和指针来表示和操作树节点,使用递归或者迭代的方式来构建霍夫曼编码树,并将编码结果写入文件或者内存中。
2. LZ77(Lempel-Ziv 77)是一种基于字典的无损压缩算法,它利用了重复出现的字符串来进行压缩。
在C语言中,可以使用滑动窗口和哈希表等数据结构来实现LZ77算法,通过扫描输入数据流,找到重复的字符串并生成对应的指针和长度,然后将结果写入文件或者内存中。
3. LZW(Lempel-Ziv-Welch)是一种自适应字典压缩算法,它能够根据输入数据动态地更新字典,以实现更好的压缩效果。
在C语言中,可以使用哈希表或者树结构来表示和操作字典,通过不断扫描输入数据,找到新的字符串并加入字典,然后将编码结果写入文件或者内存中。
以上只是介绍了几种常见的二进制压缩算法,在实际使用时,还需要考虑数据类型、压缩率、速度等因素来选择合适的算法。
另外,为了方便使用,也可以使用第三方库或者开源项目来实现二进制压缩功能。
1。
数据结构实验哈夫曼树及哈夫曼编码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,表示哈夫曼树的节点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
} printf("HT List:\n"); printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n"); for(i=1;i<=m;i++) printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n", i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); HC=(HuffmanCode)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char *)); cd[n-1]='\0'; for(i=1;i<=n;i++) { start=n-1; for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) if(HT[f].lchild==c) cd[--start]='0'; else cd[--start]='1'; HC[i]=(char *)malloc((n-start)*sizeof(char *)); strcpy(HC[i],&cd[start]); } free(cd); return HC; } MinCode Select(HuffmanTree HT,unsigned int n) { unsigned int min,secmin; unsigned int temp; unsigned int i,s1,s2,tempi;
如表二HuffmanCode: Number 1 2 3 Weight 5 29 7 Code 0110 10 1110
4 5 6 7 8
8 14 23 3 11
1111 110 00 0111 010
Hale Waihona Puke printf("w[%d]=",i); scanf("%d",&w[i]); } HC=HuffmanCoding(HT,HC,w,n); printf("HuffmanCode:\n"); printf("Number\t\tWeight\t\tCode\n"); for(i=1;i<=n;i++) printf("%d\t\t%d\t\t%s\n",i,w[i],HC[i]); }
2.霍夫曼编码的步骤
(l)将信号源的符号按照出现概率递减的顺序排列。 (2)将两个最小出现概率进行合并相加,得到的结果作为 新符号的出现概率。 (3)重复进行步骤1和2直到概率相加的结果等于1为止。 (4)在合并运算时,概率大的符号用编码0表示,概率小
的符号用编码1表示。 (5)记录下概率为1处到当前信号源符号之间的0,l序 列,从而得到每个符号的编码。 例如: 设信号源为 s={s1, s2, s3, s4, s5} 对应的概率为p={0.25,0.22,0.20, 0.18,0.15}。 根据字符出现的概率来构造平均长度最短的异字头码字。 霍未曼编码通常采用两次扫描的办法,第一次扫描得到统计结 果,第二次扫描进行编码。
《信息处理与编码》结课大作业
学号: 班级: 姓名: 成绩:
霍夫曼编码的C语言实现 1.编码原理
霍夫曼码由霍夫曼树构造,平均码长是霍夫曼树的带权
路径长度,由于霍夫曼树是权最小的树,故其压缩效果最好。 霍夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常 应用于数据压缩。 在计算机信息处理中,“霍夫曼编码”是 一种一致性编码法(又称"熵编码法"),用于数据的无损耗压 缩。这一术语是指使用一张特殊的编码表将源字符(例如某文 件中的一个符号)进行编码。这张编码表的特殊之处在于,它 是根据每一个源字符出现的估算概率而建立起来的。 霍夫曼码是用概率匹配方法进行信源编码。有两个明显 特点:一是保证了概率大的符号对应于短码,概率小的对应于 长码,充分利用了短码;二是缩减信源的最后二个码字总是最 后一位不同,从而保证了霍夫曼码是即时码。 霍夫曼变长码的效率很高,它可以单个信源符号编码或 用L较小的信源序列编码,对编码器的设计来说也易实现,但 要注意,更高效率的编码仍须按长序列来计算,这样才能使平 均码字降低。
s2=i; } if(s1>s2) { temp=s1; s1=s2; s2=temp; } code.s1=s1; code.s2=s2; return code; } void main() { HuffmanTree HT=NULL; HuffmanCode HC=NULL; unsigned int *w=NULL; unsigned int i,n; clrscr(); printf("Input n:\n"); scanf("%d",&n); w=(unsigned int *)malloc((n+1)*sizeof(unsigned int *)); w[0]=0; printf("Enter weight:\n"); for(i=1;i<=n;i++) {
typedef struct { unsigned int s1; unsigned int s2; } MinCode; void Error(char *message); HuffmanCode HuffmanCoding(HuffmanTree HC,unsigned int *w,unsigned int n); MinCode Select(HuffmanTree HT,unsigned int n); void Error(char *message) { clrscr(); fprintf(stderr,"Error:%s\n",message); exit(1); } HuffmanCode HuffmanCoding(HuffmanTree HC,unsigned int *w,unsigned int n) { unsigned int i,s1=0,s2=0; HuffmanTree p; char *cd; unsigned int f,c,start,m; MinCode min; HT,HuffmanCode HT,HuffmanCode
3.编码程序
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <malloc.h> #include <conio.h> typedef struct { unsigned int weight; nsigned int parent,lchild,rchild; } HTNode,*HuffmanTree; typedef char **HuffmanCode;
MinCode code; s1=1;s2=1; for(i=1;i<=n;i++) if(HT[i].parent==0) { min=HT[i].weight; s1=i; break; } tempi=i++; for(;i<=n;i++) if(HT[i].weight<min&&HT[i].parent==0) { min=HT[i].weight; s1=i; } for(i=tempi;i<=n;i++) if(HT[i].parent==0&&i!=s1) { secmin=HT[i].weight; s2=i; break; } for(i=1;i<=n;i++) if(HT[i].weight<secmin&&i!=s1&&HT[i].parent==0) { secmin=HT[i].weight;
if(n<=1) Error("Code too small!"); m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(p=HT,i=0;i<=n;i++,p++,w++) { p->weight=*w; p->parent=0; p->lchild=0; p->rchild=0; } for(;i<=m;i++,p++) { p->weight=0; p->parent=0; p->lchild=0; p->rchild=0; } for(i=n+1;i<=m;i++) { min=Select(HT,i-1); s1=min.s1; s2=min.s2; HT[s1].parent=i; HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight;
程序运行: 首先用户先输入一个数n,以实现n个节点的Huffman Tree 之后输入权值w[1]~w[n],注意是unsigned int型数值。 然后程序自动生成Huffman Tree的存储形式的一张表格。 最后是Huffman Coding。
Sample Input: Input n: 8 Enter weight: w[1]=5 w[2]=29 w[3]=7 w[4]=8 w[5]=14 w[6]=23 w[7]=3
w[8]=11 Sample Output: : Number weight 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 5 29 7 8 14 23 3 11 8 15 19 29 42 58 100 如表1 HT List parent 9 14 10 10 12 13 9 11 11 12 13 14 15 15 0 lchild 0 0 0 0 0 0 0 0 1 3 8 5 6 2 13 0 0 7 4 9 10 11 12 14 0 0 0 0 rchild 0 0