SSL_1409【【树】哈夫曼树(三)】

【树】哈夫曼树(三)

题目

根据输入的一串字符出现的频率,设置其相应的哈夫曼编码

Input

一串字符

Output

哈夫曼编码(按照中序遍历输出各个字母和编码,中间用冒号分开)

Sample Input

XINNNMM

Sample Output

N:0
M:10
X:110
I:111

解析

相比SSL_1408来说,本题少了一个string保存答案,但也多了一个map,总体难度差不多
具体实现见代码(反正也加注释)

code:

#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,x[10010],r,j;
struct tree{int s,l,r,id;char a;string e;}a[1000010];
string c;
char q[1000010];
inline void dfs(int x,int dep)
{
	if((!a[x].l)&&(!a[x].r)){cout<<a[x].a<<':';for(int i=0;i<dep;++i)cout<<q[i];cout<<endl;return;}
	//无儿子节点,显然该点需输出
	if(a[x].l)q[dep]='0',dfs(a[x].l,dep+1);//访问左节点
	if(a[x].r)q[dep]='1',dfs(a[x].r,dep+1);//访问右节点
}
inline bool cmp(int x,int y){return (a[x].s!=a[y].s)?(a[x].s>a[y].s):(a[x].id>a[y].id);}
map <int,int> o2;
int main()
{
	getline(cin,c);
	for(int i=0;i<c.size();++i)o2[c[i]]++;//累加权值
	for(int i=0;i<c.size();++i)if(o2[c[i]]){a[++n].s=o2[c[i]],a[n].a=c[i],o2[c[i]]=0,x[n]=a[n].id=n;}//取出权值
	sort(x+1,x+n+1,cmp);
	for(int i=n;i>1;--i)
	{
		r=(n<<1)-i+1;
		a[r].s=a[x[i]].s+a[x[i-1]].s,a[r].l=x[i],a[r].r=x[i-1],a[r].id=r;
		for(j=i-1;j&&cmp(r,x[j]);--j)x[j+1]=x[j];
		x[j+1]=r;//哈夫曼树模板
	}
	dfs((n<<1)-1,0);//DFS输出方案
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用中提到的,优先队列的时间复杂度为O(logn),其中n为队列中元素的个数。因此,使用priority_queue实现哈夫曼树的时间复杂度为O(nlogn),其中n为哈夫曼树中叶子节点的个数。 实现哈夫曼树的步骤如下: 1. 统计每个字符在文本中出现的频率,并将其作为权值构建一个森林,每个节点都是一棵只包含一个字符的。 2. 从森林中选出两棵根节点权值最小的,将它们合并成一棵新,新的根节点权值为两棵的根节点权值之和。 3. 将新插入到森林中,并删除原来的两棵。 4. 重复步骤2和3,直到森林中只剩下一棵,即为哈夫曼树。 下面是使用priority_queue实现哈夫曼树的C++代码示例: ```c++ #include <iostream> #include <queue> using namespace std; struct TreeNode { char ch; int freq; TreeNode *left, *right; TreeNode(char c, int f) : ch(c), freq(f), left(NULL), right(NULL) {} }; struct cmp { bool operator() (TreeNode* a, TreeNode* b) { return a->freq > b->freq; } }; TreeNode* buildHuffmanTree(string s) { int n = s.size(); vector<int> freq(256, 0); for (int i = 0; i < n; i++) { freq[s[i]]++; } priority_queue<TreeNode*, vector<TreeNode*>, cmp> pq; for (int i = 0; i < 256; i++) { if (freq[i] > 0) { pq.push(new TreeNode(i, freq[i])); } } while (pq.size() > 1) { TreeNode* left = pq.top(); pq.pop(); TreeNode* right = pq.top(); pq.pop(); TreeNode* parent = new TreeNode('#', left->freq + right->freq); parent->left = left; parent->right = right; pq.push(parent); } return pq.top(); } int main() { string s = "hello world"; TreeNode* root = buildHuffmanTree(s); // do something with the Huffman tree return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值