哈夫曼编码与解码代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
using namespace std;

typedef struct node{
	char ch;                          //存储该节点表示的字符,只有叶子节点用的到
	int val;                          //记录该节点的权值
	struct node *self,*left,*right;   //三个指针,分别用于记录自己的地址,左孩子的地址和右孩子的地址
	friend bool operator <(const node &a,const node &b) //运算符重载,定义优先队列的比较结构
	{
		return a.val>b.val;           //这里是权值小的优先出队列
	}
}node;

priority_queue<node> p;                //定义优先队列
char res[30];                          //用于记录哈夫曼编码
void dfs(node *root,int level)         //打印字符和对应的哈夫曼编码
{
	if(root->left==root->right)        //叶子节点的左孩子地址一定等于右孩子地址,且一定都为NULL;叶子节点记录有字符
	{
		if(level==0)                   //“AAAAA”这种只有一字符的情况
		{
			res[0]='0';
			level++;
		}
		res[level]='\0';               //字符数组以'\0'结束
		printf("%c=>%s\n",root->ch,res);
	}
	else
	{
		res[level]='0';                //左分支为0
		dfs(root->left,level+1);
		res[level]='1';                //右分支为1
		dfs(root->right,level+1);
	}
}
void huffman(int *hash)                //构建哈夫曼树
{
	node *root,fir,sec;
	for(int i=0;i<26;i++)              //程序只能处理全为大写英文字符的信息串,故哈希也只有26个
	{
		if(!hash[i])                   //对应字母在text中未出现
			continue;
		root=(node *)malloc(sizeof(node));          //开辟节点
		root->self=root;                            //记录自己的地址,方便父节点连接自己
		root->left=root->right=NULL;                //该节点是叶子节点,左右孩子地址均为NULL
		root->ch='A'+i;                             //记录该节点表示的字符
		root->val=hash[i];                          //记录该字符的权值
		p.push(*root);                              //将该节点压入优先队列
	}
    //下面循环模拟建树过程,每次取出两个最小的节点合并后重新压入队列
    //当队列中剩余节点数量为1时,哈夫曼树构建完成
	while(p.size()>1)
	{
		fir=p.top();p.pop();      //取出最小的节点
		sec=p.top();p.pop();      //取出次小的节点
		root=(node *)malloc(sizeof(node));          //构建新节点,将其作为fir,sec的父节点
		root->self=root;                            //记录自己的地址,方便该节点的父节点连接
		root->left=fir.self;      //记录左孩子节点地址
		root->right=sec.self;     //记录右孩子节点地址
		root->val=fir.val+sec.val;//该节点权值为两孩子权值之和
		p.push(*root);            //将新节点压入队列
	}
	fir=p.top();p.pop();          //弹出哈夫曼树的根节点
	dfs(fir.self,0);              //输出叶子节点记录的字符和对应的哈夫曼编码
}
int main()
{
	char text[100];
	int hash[30];
	memset(hash,0,sizeof(hash));  //哈希数组初始化全为0
	scanf("%s",text);             //读入信息串text
	for(int i=0;text[i]!='\0';i++)//通过哈希求每个字符的出现次数
	{
		hash[text[i]-'A']++;      //程序假设运行的全为英文大写字母
	}
	huffman(hash);
	return 0;
}

输入用例:

ABACDBAABC

 

输出示例:

A=>0
B=>10
D=>110
C=>111

 

后续解释有空再补,代码暂时先存着

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值