0
点赞
收藏
分享

微信扫一扫

霍夫曼编码(贪心)

目录

1.什么叫霍夫曼编码

2.如何手工运算得到霍夫曼编码

3.完整源码

(1)只输出权值

(2)输出树形


1.什么叫霍夫曼编码

 


2.如何手工运算得到霍夫曼编码

前缀码:编码的任意前缀不是其他编码 

解码结果唯一,编码方式可行

问题:如何求得编码后二进制串总长最短的前缀码?

优先处理低频字符

⚫ 将字符频数从小到大排序 𝑭 =< 𝒇𝟏, 𝒇𝟐, … , 𝒇𝒏 > (𝒇𝟏 ≤ 𝒇𝟐 ≤ ⋯ ≤ 𝒇𝒏)

⚫ 选择两个最小的频数𝒇𝟏, 𝒇𝟐,合并为𝒇 ′ = 𝒇𝟏 + 𝒇𝟐 

 

 


⚫在𝑭 ′ =< 𝒇′, 𝒇𝟑, … , 𝒇𝒏 > 中重复选择合并过程 

 


 

 


 

 


 

 


 


3.完整源码

(1)只输出权值

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
int main()
{
	int n;
	cin>>n;
	int x;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		q.push(x);
	}
	while(q.size()>1)
	{
		int x,y;
		x=q.top();
		q.pop();
		y=q.top();
		q.pop();
		q.push(x+y);
	}
	cout<<q.top()<<endl;
}

 (2)输出树形

#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstdlib>
#include<vector> 
using namespace std;
struct node//结构体 
{
	int sum;//该点权值 
	node *left;
	node *right;
};
node an[10010];
bool cmp1(node a,node b){return a.sum<b.sum;}
class cmp//排序规则 
{
	public:
		bool operator()(node *a,node *b)
		{
			return a->sum>b->sum;
		}
};
priority_queue<node *,vector<node *>,cmp > q;//优先队列  递增排序 
int main()
{
	int n;
	cin>>n;//建立有n个点的Huffman树 
	int x;
//(这里如果直接输入值插入队列里面有点bug,得按规律输入,改不出来了QAQ,
// 只好先输入一组数据排序后再插入队列里面)
	for(int i=0;i<n;i++)//输入各点权值
	{
		cin>>an[i].sum;
		an[i].left=NULL;
		an[i].right=NULL;
	}
	sort(an,an+n,cmp1);
	for(int i=0;i<n;i++)
	{
		q.push(an+i);
	}
	while(q.size()>1)//按权值从小到大建树 
	{
		node *a;//取两个最小点合并 
		a=(node*)malloc(sizeof(node));
		a->sum=0;
		a->left=q.top();
		a->sum+=q.top()->sum;
		q.pop();
		a->right=q.top();
		a->sum+=q.top()->sum;
		q.pop(); 
		
		q.push(a);//把新点放入优先队列 
		//cout<<"push增加成功"<<endl;
	}
	node *gen;
	gen=q.top();
	queue<node *> q2;
	queue<node *> q3;
	q2.push(gen);
	cout<<"该huffman树形大概为:"<<endl;
	while(q2.size()>0)
	{
		if(q2.front()==NULL)
		{
			q2.pop();
			continue;
		}
		q3.push(q2.front()->left);
		q3.push(q2.front()->right);
		cout<<q2.front()->sum<<" ";
		q2.pop();
		if(q2.size()==0)
		{
			while(q3.size()>0)
			{
				q2.push(q3.front());
				q3.pop();
			}
			cout<<endl;
		}
	}
	cout<<"该huffman树权值:"<<gen->sum<<endl;//根节点权值就是这个Huffman树权值 
	return 0;
}

举报

相关推荐

0 条评论