数据结构——Huffman编码及译码

Huffman编码及译码

1.掌握二叉树的二叉链表存贮结构。

2.掌握Huffman算法。

 

要求:

使用文件保存初始的文本数据及最终的结果。

  1. 文件名为inputfile1.txt的文件保存的是一段英文短文;
  2. 文件名为inputfile2.txt的文件保存01形式的编码段;
  3. 文件名为outputfile1.txt的文件保存各字符的出现次数和对应的编码;
  4. 文件名为outputfile2.txt的文件保存对应于inputfile2.txt的译码结果。

统计inputfile1.txt中各字符的出现频率,并据此构造Huffman树,编制Huffman 码;根据已经得到的编码,对01形式的编码段进行译码。

具体的要求:

1.将给定字符文件编码,生成编码,输出每个字符出现的次数和编码;

2.将给定编码文件译码,生成字符,输出编码及其对应字符。

 

输入数据格式:

详见要求部分。

 

输出数据格式:

outputfile1.txt文件中:

字符  出现次数  对应的编码

 a      37         010

 b      130        00

 

outputfile2.txt文件中:

This is a example.

 

 

分析(如何构造哈夫曼树):

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:


(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);


(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;


(3)从森林中删除选取的两棵树,并将新树加入森林;


(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

 

 如:对 下图中的六个带权叶子结点来构造一棵哈夫曼树,步骤如下(借用一下他人好看的图):

数据结构——Huffman编码及译码_第1张图片

 

代码如下(vs2012):

#include
#include
#include
using namespace std;
struct Huffmannode {
	int parent;
	int lc;
	int rc;
	int weight;
};
class Huffmantree {
private:
	Huffmannode*node;
	char* letter;
	int leafnum;
public:
	Huffmantree();
	~Huffmantree();
	Huffmannode*Initialization(int sum, char z[], int w[]);
	void Encord(Huffmannode*node, char tree[], int sum, char z[], int w[]);
	void Decord(Huffmannode*node, int sum, char z[]);
};
Huffmantree::Huffmantree() {
	node = NULL;
	letter = NULL;
	leafnum = 0;
}
Huffmantree::~Huffmantree() {
	delete[]node;
	delete[]letter;
}
Huffmannode*Huffmantree::Initialization(int sum, char z[], int w[]) {
	int min1, min2;
	int loc1, loc2;
	node = new Huffmannode[2 * sum - 1];
	letter = new char[2 * sum - 1];
	for (int i = 0; i= 0) {
			shuchu << code[k];
			k--;
		}
		shuchu << '\n';
		n++;
	}
	shuchu.close();
	ofstream out;
	out.open("inputfile2.txt", ios::app);
	while (t[m] != '\0') {
		int j, s = 0;
		for (i = 0; i= 0) {
			out << code[s];
			s--;
		}
		m++;
	}
	out.close();
}
void Huffmantree::Decord(Huffmannode *node, int sum, char z[]) {
	ifstream tree("inputfile2.txt");
	int k = 0;
	char *code = new char[1000];
	while (!tree.eof()) {
		tree >> code[k];
		k++;
	}
	code[k] = '\0';
	tree.close();
	ofstream yima("outputfile2.txt", ios::app);
	k = 0;
	int j = 2 * sum - 1 - 1;
	while (code[k + 1] != '\0') {
		if (code[k] == '0') {
			j = node[j].lc;
		}
		if (code[k] == '1') {
			j = node[j].rc;
		}
		if (node[j].lc == -1) {
			yima << z[j];
			j = 2 * sum - 1 - 1;
		}
		k++;
	}
	yima.close();
}
int main() {
	ifstream in("inputfile1.txt", ios::app);
	char tree[1000] = { 0 };
	char letter[100];
	int count[100] = { 0 };
	int i = 0, t = 0;
	while (!in.eof()) {
		tree[t] = in.get();
		t++;
	}
	tree[t] = '\0';
	int k = 0;
	in.close();
	while (tree[i] != '\0') {
		int m = 0;
		for (int j = 0; j

 

你可能感兴趣的:(breadcrumb,Play,Me,——,Algorithm,and,Structure)