6.codeup-哈夫曼树-Haffman编码

77 阅读1分钟

思路

  • 和哈夫曼编码找最小节点时多了一个找最左节点的ascii码函数

注意

  • m=HT[i].weight;要放在判断语句后面,要不会死循环(找错误找了好久)。

代码

#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=101;
int n;
struct HTNode{
	int weight;
	int lchild,rchild,parent;
};
char ch[maxn];
int w[maxn];

int getlchild(HTNode *HT,int n){
	while(HT[n].lchild!=0) n=HT[n].lchild;
	return n;
}

void select(HTNode *HT,int n,int &s1,int &s2){
	int m=0xfffffff;
	for(int i=1;i<=n;i++){
		if(HT[i].parent==0&&HT[i].weight<=m){
			if(HT[i].weight!=m){
				s1=i;
			}
			else {
				if(ch[getlchild(HT,s1)]>ch[getlchild(HT,i)]) s1=i;
			}
			m=HT[i].weight;          //不能在if之前 
		}
	}	
	m=0xfffffff;
	for(int i=1;i<=n;i++){
		if(HT[i].parent==0&&HT[i].weight<=m&&i!=s1){
			if(HT[i].weight!=m){
				s2=i;
			}
			else {
				if(ch[getlchild(HT,s2)]>ch[getlchild(HT,i)]) s2=i;
			}
			m=HT[i].weight;
		}
	}	
}




void HuffmanCoding(HTNode *HT,char **&HC,int n,int w[]){
	if(n<=1) return;
	int m=2*n-1;
	int s1,s2;
	HT=new HTNode[m+1];
	for(int i=1;i<=n;i++){
		HT[i].parent=HT[i].rchild=HT[i].lchild=0;
		HT[i].weight=w[i];
	}
	for(int i=n+1;i<=m;i++){
		HT[i].parent=0;
	}
	for(int i=n+1;i<=m;i++){
		select(HT,i-1,s1,s2);
		HT[s1].parent=HT[s2].parent=i;
		HT[i].lchild=s1;
		HT[i].rchild=s2;
		HT[i].weight=HT[s1].weight+HT[s2].weight;
	}
	char *cd=new char[n];
	int cdlen=0;
	HC=new char*[n+1];
	for(int i=1;i<=m;i++){
		HT[i].weight=0;
	}
	int c=m;
	while(c){
		if(HT[c].weight==0){
			HT[c].weight=1;
			if(HT[c].lchild!=0){
				c=HT[c].lchild;
				cd[cdlen++]='0';
			}
			else if(HT[c].rchild==0){
				cd[cdlen]='\0';
				HC[c]=new char[cdlen+1];
				strcpy(HC[c],cd);
			}
		}
		else if(HT[c].weight==1){
			HT[c].weight=2;
			if(HT[c].rchild!=0){
				c=HT[c].rchild;
				cd[cdlen++]='1';
			}
		}
		else {
			HT[c].weight=0;
			c=HT[c].parent;
			cdlen--;
		}
	}
}

int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=1;i<=n;i++){
			getchar();
			scanf("%c %d",&ch[i],&w[i]);
		}
		HTNode *HT;
		char **HC;
		HuffmanCoding(HT,HC,n,w);
		for(int i=1;i<=n;i++){
			printf("%c:%s\n",ch[i],HC[i]);			
		}
	}
	return 0;	
}