Huffman tree and Huffman coding analysis, source code attached (C implementation)

1. Huffman tree

1.1 Concept

In layman's terms, it means to select the smallest two among a bunch of numbers as leaf nodes, and their sum is their parent node.

As shown in the picture:

As for how to construct it, it depends on your mood, because the binary tree is not unique in its structure, which is also the characteristic of its isomorphism and isomorphism. If it's characters A, B, C, D...just look at the frequency of each character!

1.2 Create Huffman tree

1.21 Huffman tree structure

typedef struct {
	int weight;
	int parent,lchild,rchild;
}HTNode,HuffmanTree[M+1];

1.22 Select the smallest two weight functions

In the judgment, the judgment of the parent node plays a filtering role, with the purpose of excluding already selected values.

typedef struct {   //定义一个结构体  更直观
	int falg1;
	int falg2;
}MIN;

//挑选 2 个权值最小的结点
MIN select (HuffmanTree ht,int len){
	int k=1;
	MIN check; 
	int min1,min2,falg1,falg2;
	min1=100;
	min2=100;
	//目的是 s1 的权值要不大于 s2 的权值
	for(k;k<=len;k++){
		if((ht[k].weight)<min1&&ht[k].parent==0){  //父节点值得判断起到筛选在集合中选过和没选过得值
			min1=ht[k].weight;
			falg1=k;
		}
	}
	for(int i=1;i<=len;i++)
	{
		if(ht[i].parent==0&&(ht[i].weight<min2)&&(i!=falg1))
		{
			min2=ht[i].weight;
			falg2=i;
	}
} //这里采用结构体的办法   更直观 
	check.falg1=falg1;
	check.falg2=falg2;
	return check;
}

1.23 Building a Huffman tree

//建立哈夫曼树
void CreateHuffmanTree(HuffmanTree &ht,int w[],int n)
{	MIN flag;
	int m=2*n-1;
	int i;
	//初始化
	for(i=1;i<=n;i++){
		ht[i]={w[i-1],0,0,0};
	} 
	for(i=n+1;i<=m;i++){
		ht[i]={0,0,0,0};
	}
	//从第n+1个元素开始创建
	for(i=n+1;i<=m;i++)
	{
		flag=select(ht,i-1);
		ht[i].weight=ht[flag.falg1].weight+ht[flag.falg2].weight;  //权值相加
		ht[i].lchild=flag.falg1;
		ht[i].rchild=flag.falg2;
		ht[flag.falg1].parent=i;
		ht[flag.falg2].parent=i;
	 } 
 } 

1.24 Output Huffman tree

//输出哈夫曼树
 void show(HuffmanTree ht,int num){
 	for(int i=1;i<=num;i++)
 	{
 		printf("\n结点序号%d,权值为%d,父节点为 %d,左孩子结点为%d,右孩子结点为 %d",i,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
	}
 } 

 2. Huffman coding

First you have to use this thing:

#include<string.h>

2.1 Create

//哈夫曼编码的实现
void Huffmanbianma(HuffmanTree ht,Huffmancode hc,int n)

//从叶子节点到根逆向求各叶子结点的编码 
{
	char *cd;
	int c,p;
	int start;
	cd=(char *)malloc(n*sizeof(char)); //临时编码数组
	cd[n-1]='\0';  //从后往前逐位求编码,最后一位是结束符先放
	for(int i=1;i<=n;i++)
	{
		start=n-1;  //因为是逆序,所以指针start从最后开始 
		c=i;        //当前结点,因为后面要进行指针的修改 
		p=ht[i].parent;  //取当前结点的父节点
		while(p!=0)
		{
			--start;
			if(ht[p].lchild==c)
			{
				cd[start]='0';  //左分支0  
			}else{
				cd[start]='1';   //右分支 1 
			}
			c=p; p=ht[p].parent;  //网上一层;	
		}
		hc[i]=(char *)malloc((n-start)*sizeof(char)); 
		strcpy(hc[i],&cd[start]);	
	}
	free(cd);	 
}

2.2 Traversal

//遍历哈夫曼编码,也就是译码 
void TraverseCoding(Huffmancode HC, int n) {
	for (int i = 1; i <= n; ++i) {
		printf("哈夫曼编码:");
		puts(*(HC + i));
	}
}

Because I don’t have time to explain, the code process can be implemented. I directly define the array during all the creation process, because it saves trouble~~~~

Guess you like

Origin blog.csdn.net/m0_61395860/article/details/123077862