数据结构:构造哈夫曼树和哈夫曼编码的算法实现

题目:

统计下面一段英文的不同字符个数和每个字符的出现频率,利用统计数据构造构造哈夫曼树和哈夫曼编码
The Chinese official said he viewed the Trump Presidency not as an aberration but as the product of a failing political system. This jibes with other accounts. The Chinese leadership believes that the United States, and Western democracies in general, haven’t risen to the challenge of a globalized economy, which necessitates big changes in production patterns, as well as major upgrades in education and public infrastructure. In Trump and Trumpism, the Chinese see an inevitable backlash to this failure.

思路:

(1) 写一个找出双亲值为0,且权重最小的两个值。
(2) 利用map进行字符与出现频率的映射
(3) 写哈夫曼树表函数
(4) 写哈夫曼编码函数
(5) 输出哈夫曼表和哈夫曼编码

代码块:

#include "pch.h"
#include <iostream>
#include<map>
#include<string>
#include<iomanip>
#include<vector>
using namespace std;
struct Huffmantree {
	int weight;
	int parent;
	int lchild;
	int rchild;
};
void select(Huffmantree *&ht, int i, int &s1, int &s2)//找出哈夫曼树表最小的两个数
{
	int j = 1;
	int k = 1;
	while (ht[k].parent != 0) k++;//找出双亲为0的标号
	s1 = k;
	for (j = 1; j <= i; j++)
	{//找出最小值
		if (ht[j].parent == 0 && ht[j].weight <= ht[s1].weight)
		{
			s1 = j;
		}
	}
	k = 1;
	while (ht[k].parent != 0||k==s1) k++;
	s2 = k;
	for (j = 1; j <= i; ++j)
	{//找出第二小值
		if (ht[j].parent == 0 && ht[j].weight <= ht[s2].weight&&j != s1)
		{
			s2 = j;
		}
	}
}
void CreatHuffmantree(Huffmantree *&ht, int n, map<char, int>tmp)
{
	if (n <= 1) {//空树处理
		cout << "树为空树!" << endl; return;
	}
	int m = 2 * n-1;
	int s1;
	int s2;
	ht = new Huffmantree[m+1];//创建哈夫曼表
	for (int i = 1; i <= m; i++)
	{//将哈夫曼表的双亲,左右子树均置0
		ht[i].parent = 0;
		ht[i].lchild = 0;
		ht[i].rchild = 0;
	}
	int i = 1;
	for (auto e : tmp)
	{//将字符出现频率作为权重输入哈夫曼表
		ht[i].weight = e.second;
		i++;
	}
	for ( i = n+1; i <= m; i++)
	{
		select(ht, i-1, s1, s2);
		ht[s1].parent = i;//置双亲
		ht[s2].parent = i;
		ht[i].lchild = s1;//输入i的左右子树
		ht[i].rchild = s2;
		ht[i].weight = ht[s1].weight + ht[s2].weight;//值i的权重
	}
}

void CreateHuffmanCode(Huffmantree *ht,vector<string> &hc, int index,int position)//创建哈夫曼树编码
{
	while (ht[position].parent!=0)
	{//当结点有双亲时
		int temp = ht[position].parent;//记录结点双亲位置
		if (ht[temp].lchild == position)//判断结点是属于双亲的左节点还是右结点,若左,则编码置0,若右,编码置1
			hc[index].insert(hc[index].begin(), '0');
		else if (ht[temp].rchild == position)
			hc[index].insert(hc[index].begin(), '1');
		position = ht[position].parent;//将结点位置置为双亲位置
	}
}
int main()
{
	map<char, int>tmp;//map映射字符与出现频率
	string data = "The Chinese official said he viewed the Trump Presidency not as an aberration but as the product of a failing political system. This jibes with other accounts. The Chinese leadership believes that the United States, and Western democracies in general, haven't risen to the challenge of a globalized economy, which necessitates big changes in production patterns, as well as major upgrades in education and public infrastructure. In Trump and Trumpism, the Chinese see an inevitable backlash to this failure.";
	for (auto e : data)//对文段进行统计
	{
		tmp[e]++;		
	}
	cout << "字符统计结果:" << endl;
	cout << "字符" << setw(6) << "数量" << endl;
	vector<char> letter;
	letter.push_back(' ');
	for (auto e : tmp)
	{
		cout <<e.first << '\t' << e.second<<endl;
		letter.push_back(e.first);
	}//输入文段统计结果,并把字符出现频率记录到vector中
	Huffmantree *tree;
	CreatHuffmantree(tree, tmp.size(), tmp);//建立哈夫曼树
	cout << endl << "要求的哈夫曼树如下所示:" << endl;
	cout << "结点i" << setw(8) << "weight" << setw(8) << "parent" << setw(8) << "lchild" << setw(8) << "rchild" << endl;
	for (int i = 1; i < tmp.size()*2; i++)
	{
		if (i <= tmp.size())
			cout << i << setw(8) << tree[i].weight << setw(8) << tree[i].parent << setw(8) << tree[i].lchild << setw(8) << tree[i].rchild <<setw(8)<< letter[i] << endl;
		else
		cout << i << setw(8) << tree[i].weight << setw(8) << tree[i].parent << setw(8) << tree[i].lchild<< setw(8) << tree[i].rchild<< endl;
	}//输出哈夫曼树表
	vector<string> hc(tmp.size()+1, "");//建立vector存放哈夫曼编码,将string全初始化为空串
	cout<<endl << "各个字符的哈夫曼编码如下:" << endl;
	for (int i = 1; i <= tmp.size(); i++)
	{
		CreateHuffmanCode(tree, hc, i, i);
		cout << letter[i] << ":" << hc[i] << endl;
	}//输出哈夫曼编码
}

效果图:

图一二为英文文段各字符的统计结果,图三四五是哈夫曼树表,图六七是各个字符哈夫曼编码。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了330 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43981315/article/details/103915170