Huffaman coding

Programming Huffman coding, and provide the test example 

#include <iostream>
#include <queue>
#include <vector> 
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 50
#define MAXT 100
 
//结果返回一棵完全二叉树,里面包含其中的编码方式 
//输入N,接下来输入N个数,代表出现次数,然后输出每个叶子节点的编码
struct Node{
	int num,w;//num表示这个节点在Tree数组中的下标
	int f,lc,rc;//f=father,lc=left_child,rc=right_child
	bool operator <(const Node b)const{
		return w>b.w;
	} //优先队列的比较方式 
}Tree[MAXT+5];

char Ans[MAXN+5];
int N,size,Root;
priority_queue<Node> Q; 
void unite(Node x,Node y){//将x和y结点合并到一起 这个函数太重要了 
	Tree[x.num].f=Tree[y.num].f=++size;//记住 size是一个全局变量 合成的新节点重新加入加入这个队列 
	Tree[size].lc=x.num;
	Tree[size].rc=y.num;
	Tree[size].num=size;
	Tree[size].w=Tree[x.num].w+Tree[y.num].w;
	Q.push(Tree[size]);//放入队列 
}
void print(int u,int Len)//Len记录长度 其实真正的难点在于寻找这个编码方式 
{
    if(!Tree[u].lc&&!Tree[u].rc){
		cout<<Tree[u].w<<":";
		puts(Ans+1);
		return;
	}
    Len++;
    Ans[Len]='0';
    print(Tree[u].lc,Len);
    Ans[Len]='1';
    print(Tree[u].rc,Len);
    Ans[Len]=0;
}
int main(){
	int n;//n个数字 
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>Tree[i].w;
		Tree[i].num=i;//num记录的是初始时的下标1~n 
		Q.push(Tree[i]);//优先队列 实际上已经更改了优先级 权值越小 优先级别越高 
	}
	if(n==1)
	cout<<0<<endl;//特殊情况判断 
	size=n;//初始时size记录结点的序号 
	for(int i=1;i<n;i++){//从1~n进行循环遍历 可以认为出队列 
		Node u1=Q.top();
		Q.pop();
		Node u2=Q.top();
		Q.pop();
		unite(u1,u2);//这一步很重要 需要将pop出去的两个数合在一起 然后放到优先队列里面 
	}
	for(int i=1;i<=size;i++){//find root 
		if(!Tree[i].f)
			Root=i;
	}
	print(Root,0);
	
	return 0;
}
//6
//45 13 12 16 9 5

 

Published 43 original articles · won praise 23 · views 5322

Guess you like

Origin blog.csdn.net/weixin_43442778/article/details/89456650