Huffman树(哈夫曼树,c++)

题目描述
对输入的英文大写字母进行统计概率 然后构建哈夫曼树,输出是按照概率降序排序输出Huffman编码。
输入
大写字母个数 n
第一个字母 第二个字母 第三个字母 … 第n个字母。
输出
字母1 出现次数 Huffman编码
字母2 出现次数 Huffman编码
字母3 出现次数 Huffman编码

字母n 出现次数 Huffman编码

样例输入
10
I I U U U I U N U U
样例输出
U 6 1
I 3 01
N 1 00

如果大家不了解哈夫曼树是什么,可以看一下这篇博客哈夫曼树

这还有一个视频 视频
哈夫曼树(Huffman Tree)是在叶子结点和权重确定的情况下,带权路径长度最小的二叉树,也被称为最优二叉树。也就是说我们需要将权重大的靠近根结点,权重小的远离根节点
Huffman树(哈夫曼树,c++)_第1张图片

#include 
#include 
#include 

using namespace std;

struct Node {
	char name=' ';
	int code[200];
	int num = 0;//code的下标
	int weight = 0;//权重(次数)
	Node* lchild;//左孩子
	Node* rchild;//右孩子
	Node* parent;
	Node* rparent;
	Node* lparent;
	Node() {}
	Node(char c, Node* lc = nullptr, Node* t = nullptr) {
		name = c;
		lchild = rchild = t;
		parent = rparent = lparent = t;
	}
	Node(int n, Node* lc = nullptr, Node* t = nullptr) {
		weight = n;
		lchild = rchild = t;
		parent = rparent = lparent = t;
	}
};

void sort(Node** arr, int n) {//排序
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < n - 1 - i; j++) {
			if (arr[j]->weight <= arr[j + 1]->weight) {
				Node* t = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = t;
			}
		}
	}
}


Node* solve(Node** arr, int len) {
	Node* parent = nullptr;
	while (len != 0) {
		sort(arr, len);
		Node* first = arr[len-1];
		Node* second = arr[len-2];
		len -= 2;

		parent = new Node(first->weight + second->weight);
		parent->lchild = first;
		parent->rchild = second;
		first->parent = second->parent = parent;
		first->rparent = second->lparent = parent;

		if (len == 0)
			return parent;

		arr[len] = parent;
		len++;
	}
	return nullptr;
}

void seekCode(Node* tree, char c) {
	queue<Node*> q;
	q.push(tree);
	while (!q.empty()) {
		Node* t = q.front();
		q.pop();
		if (t->name == c) {//找到
			Node* t1 = t;
			Node* t2 = t1->parent;
			while (t2 != nullptr) {
			//判断父子关系
				if (t2->lchild == t1 && t1->rparent == t2 ) t->code[t->num] = 0;
				else t->code[t->num] = 1;
				t->num++;
				t1 = t2;
				t2 = t1->parent;
			}
			break;
		}
		if(t->lchild != nullptr)
			q.push(t->lchild);
		if(t->rchild != nullptr)
			q.push(t->rchild);
	}
}

int main() {
	int n;
	int len = 0;//代表元素的个数
	cin >> n;
	char c;
	Node** arr = new Node*[10000];
	Node** temp = new Node*[10000];
	//-------------得到每个字母出现的次数
	for (int i = 0; i < n; i++) {
		cin >> c;
		int flag = 0;
		for (int j = 0; j < len; j++) {
			if (arr[j]->name == c) {
				flag = 1;
				arr[j]->weight++;
				break;
			}
		}
		if (!flag) {
			arr[len] = new Node(c);
			arr[len]->weight++;
			len++;
		}
	}

	//---------------备用
	sort(arr, len);
	for (int i = 0; i < len; i++)
		temp[i] = arr[i];

	//----------------构建哈夫曼树
	Node* tree = solve(arr, len);

	for (int i = 0; i < len; i++)
		seekCode(tree, temp[i]->name);

	for (int i = 0; i < len; i++) {
		cout << temp[i]->name << " " << temp[i]->weight << " ";
		for (int j = temp[i]->num-1 ; j >= 0; j--)
			cout << temp[i]->code[j];
		cout << endl;
	}

}

上面的程序纯原创,我个人感觉写的比较复杂,但感觉写的挺直白(hh),大家有更好的想法,欢迎评论留言

你可能感兴趣的:(数据结构,c++,算法,数据结构)