【数据结构】哈夫曼树前期准备(一)

哈夫曼树以及文件压缩的实现

注意: 所有的准备工作只是为了将这个题目分解成很多小问题解决,而最终我写的哈夫曼解压缩代码会与准备工作有很大区别。

前期准备

随机生成0~127的数

#include<math.h>
#include<time.h>
#include<stdlib.h>
int main() {
	int n;
	srand(time(NULL));
	for (int i = 0; i < 10; i++) {
		n = rand() % 128;
		cout << n << " ";
	}
	
}

在这里插入图片描述
在这里插入图片描述
输出随机生成的数对应的ASCLL字符

#include<iostream>
using namespace std;
#include<math.h>
#include<time.h>
#include<stdlib.h>
int main() {
	srand(time(NULL));
	char c;
	for (int i = 0; i < 10; i++) {
		c = rand() % 128;
		cout << c << " ";
	}
	
}

随机生成1024个字符,写入文件中

#include<iostream>
using namespace std;
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<fstream>
int main() {
	srand(time(NULL));
	ofstream ofs;
	ofs.open("D:\\data.txt", ios::out);
	char c;
	for (int i = 0; i < pow(2, 10); i++) {
		c = rand() % 128;
		ofs << c;
	}

	ofs.close();	
}

在这里插入图片描述

#include<iostream>
using namespace std;
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<fstream>
int main() {
	srand(time(NULL));
	char c = 32;
	for (int i = 0; i < 95; i++) {
		if (i % 10 == 0)
			cout << "\n";
		cout << c<<" ";
		c++;
	}
	
	
	
}

在这里插入图片描述
现在我想向文件随意输入ASCLL码在32~126之间的字符

#include<iostream>
using namespace std;
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<fstream>
int main() {
	srand(time(NULL));
	ofstream ofs;
	ofs.open("D:\\data.txt", ios::out);
	char c;
	for (int i = 0; i < pow(2, 10); i++) {
		c = 32 + rand() % 95;
		ofs << c;
	}

	ofs.close();
}

在这里插入图片描述
在这里插入图片描述
向大家简单介绍一个,一个char型在内存中大小为1个字节,一个字节 = 8个比特位,一个比特位就是我们所熟知的二进制0和1。
在这里插入图片描述
计算文件中每个字符的个数

#include<iostream>
using namespace std;
#include<fstream>
#include<unordered_map>
int main() {
	ifstream ifs;
	ifs.open("D:\\data.txt", ios::in);
	unordered_map<char, int> map;
	char c;
	while ((c = ifs.get()) != EOF) {
		map[c]++;
	}
	ifs.close();
	unordered_map<char, int>::iterator it = map.begin();
	for (; it != map.end(); it++) {
		cout << it->first << " " << it->second << "\n";
	}




}

优先级队列
这个内容应该使用小根堆实现的,但是偷个懒直接用现成给的了。
#include < queue >就好了

优先队列 按照由小到大顺序

这个作用是每次从队列里出来的数是队列中最小的数。

当然,优先级队列默认是每次从队列里出来的数是队列中最大的数

#include<iostream>
using namespace std;
#include<queue>
int main() {
	priority_queue<int, vector<int>, greater<int>> q;
	int arr[] = { 54,26,93,17,77,31,44,55,20 };
	for (int i = 0; i < 9; i++) {
		q.push(arr[i]);
	}
	int n;
	for (int i = 0; i < 9; i++) {
		n = q.top();
		q.pop();
		cout << n << " ";
	}

}

在这里插入图片描述
优先队列 按照由小到大顺序

#include<iostream>
using namespace std;
#include<queue>
struct huffmanNode
{
	char element;
	int weight;
	huffmanNode* leftChild, * rightChild;
	huffmanNode(char element = NULL, int weight = 0, huffmanNode* leftChild = NULL,
		huffmanNode* rightChild = NULL) {
		this->element = element;
		this->weight = weight;
		this->leftChild = leftChild;
		this->rightChild = rightChild;
	}
	
};
struct cmp
{
	bool operator()(huffmanNode* x, huffmanNode* y) {
		return x->weight > y->weight;
	}

};
int main() {
	priority_queue<huffmanNode*,vector<huffmanNode*>,cmp> q;
	huffmanNode* h1 = new huffmanNode('a', 5);
	huffmanNode* h2 = new huffmanNode('b', 7);
	huffmanNode* h3 = new huffmanNode('c', 3);

	q.push(h1);
	q.push(h2);
	q.push(h3);

	huffmanNode* cur;
	for (int i = 0; i < 3; i++) {
		cur = q.top();
		q.pop();
		cout << cur->element << " ";
	}
}

利用哈夫曼树实现文件压缩

构建哈夫曼树:
在这里插入图片描述
在这里插入图片描述

#pragma once
#include<iostream>
using namespace std;
#include<queue>
#include<unordered_map>
#include<fstream>
struct huffmanNode
{
	char element;
	int weight;
	huffmanNode* leftChild, * rightChild;
	huffmanNode(char element = NULL, int weight = 0, huffmanNode* leftChild = NULL,
		huffmanNode* rightChild = NULL) {
		this->element = element;
		this->weight = weight;
		this->leftChild = leftChild;
		this->rightChild = rightChild;
	}

};
struct cmp
{
	bool operator()(huffmanNode* x, huffmanNode* y) {
		return x->weight > y->weight;
	}

};
class huffmanTree
{
private:
	unordered_map<char, int> map_weight;
	unordered_map<char, string> map_code;
	huffmanNode* root;
public:
	huffmanTree();
	~huffmanTree();

	void createTree();
	void compressedFile(const char* path = "D:\\data.txt");
	void dispose(huffmanNode* t);
	void print();
	void print(huffmanNode* t);
	void output();
};

huffmanTree::huffmanTree()
{
	root = NULL;
}

huffmanTree::~huffmanTree()
{
	dispose(root);
	root = NULL;
}

void huffmanTree::createTree()
{
	if (map_weight.empty()) {
		cout << "未读取文件,请先读取文件!\n";
		return;
	}
	priority_queue<huffmanNode*, vector<huffmanNode*>, cmp> q;
	unordered_map<char, int>::iterator it = map_weight.begin();
	for (; it != map_weight.end(); it++) {
		huffmanNode* node = new huffmanNode(it->first, it->second);

		q.push(node);
	}

	huffmanNode* w, * x, * y;
	while (q.size() > 1) {
		x = q.top();
		q.pop();
		y = q.top();
		q.pop();
		int weight = x->weight + y->weight;
		w = new huffmanNode('?', weight, x, y);
		q.push(w);
	}

	root = q.top();


}

void huffmanTree::compressedFile(const char* path)
{
	ifstream ifs;
	ifs.open(path, ios::in);
	char c;
	while ((c = ifs.get()) != EOF) {
		map_weight[c]++;
	}
	ifs.close();


}

void huffmanTree::dispose(huffmanNode* t)
{
	if (t != NULL) {
		dispose(t->leftChild);
		dispose(t->rightChild);
		delete t;
	}
}

void huffmanTree::print()
{
	print(root);
}

void huffmanTree::print(huffmanNode* t)
{
	if (t != NULL) {
		print(t->leftChild);
		cout << t->element;
		print(t->rightChild);

	}
}

void huffmanTree::output()
{
	unordered_map<char, int>::iterator it = map_weight.begin();
	for (; it != map_weight.end(); it++) {
		cout << it->first << " " << it->second << "\n";
	}
}


test.cpp

#include<iostream>
using namespace std;
#include"huffmanTree.h"
int main() {
	huffmanTree h;
	h.compressedFile();
	h.createTree();
	h.print();
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值