Coding and Compilation of Telegrams

content:

Receive a string of text characters from the keyboard, output the corresponding Huffman code, and at the same time, translate the code string generated by the Huffman code, and output the corresponding text string.

Design requirements:

  (1). Construct a Huffman tree;

  (2). Realize Huffman coding, and use the code string generated by Huffman coding to decode;

  (3). Characters and weights in the program are variable, which realizes the flexibility of the program.

step:

Analysis of Algorithms

This design uses a structure array to store the Huffman tree.

Two functions are designed in the program:

The function HuffmanTree() is used to construct a Huffman tree;

The function HuffmanCode() is used to generate Huffman code and output it.

In telegraphic communication, messages are sent in binary code. When sending, it is necessary to convert the characters in the message into a binary code string, that is, encoding; when receiving, it is necessary to convert the received binary code string into a corresponding character sequence, that is, decoding. Since the characters in the character set are used non-uniformly, it is necessary to keep the total length of the message as short as possible when transmitting the message. Therefore, if a character set is designed with unequal length encoding, it is required that the encoding of any character is not the prefix of other character encodings. This encoding is called prefix encoding. The code obtained by the Huffman tree is the optimal prefix code, also called Huffman code. Given the character set and the probability distribution of each character, construct a Huffman tree, mark the left branch of each branch node in the Huffman tree as 0, and mark the right branch as 1, and connect the labels on the root to each leaf path, It is the encoding of the character represented by the leaf.

The main function in the program inputs some characters and their weights according to the prompts, and the program outputs Huffman codes; if a text is input, it can output Huffman codes.

1. Algorithm for constructing Huffman tree

Enter different characters in the main program, count the number of occurrences of different characters as the weight of the character, and store it in the data[] array. Assuming that there are n kinds of characters, there are n leaf nodes, and the constructed Huffman tree has 2n-1 nodes. Specific steps are as follows:

Store n characters (leaf nodes) and their weights in the first n array elements of the HuffNode array, and set the parents and left and right children of 2n-1 nodes to -1.

Among all nodes, select the parent as -1, and select the nodes m1 and m2 with the smallest and second smallest weights, use x1 and x2 to indicate the positions of these two nodes in the array, and set the root as HuffNode[x1 ] and the two trees of HuffNode[x2] are merged, making it the left and right children of the new node HuffNode[n+i], whose weight is m1+m2.

Repeat the above process, a total of n-1 merges are performed to construct a Huffman tree. The generated n-1 nodes are placed in the n~2n-2 units of the array HuffNode[].

2. Huffman encoding and decoding algorithm

Starting from the leaf node HuffNode[i] (0<=i<n) of the Huffman tree, find its parents through HuffNode [c].parent, and know whether HuffNode[c] is the left branch or the right branch through the lchild and rchild fields, if For the left branch, bit[n-1-i]=0; otherwise bit[n-1-i]=1.

Taking HuffNode[c] as the starting point, repeat the above process until the location of the root of the tree is found, that is, Huffman coding is performed.

When decoding, first input the binary code string, put it in the array code, and end the input with a carriage return.

Compare the code with the encoding table, if it is 0, turn to the left subtree; if it is 1, turn to the right subtree until the end of the leaf node. Output the data field of the leaf node, that is, the corresponding character.

Outline design:

HuffmanTree()

Construct a Huffman tree

HuffmanCode()

Generate huffman code and output

operation result:

 

 source code:

#include<stdio.h>
#include<conio.h>
#define MAXVALUE 10000
#define MAXLEAF 30
#define MAXNODE MAXLEAF*2-1
#define MAXBIT 50
#define NULL 0
typedef struct node {
	char letter;
	int weight;
	int parent;
	int lchild;
	int rchild;
} HNodeType;
typedef struct {
	char letter;
	int bit[MAXBIT];
	int start;
} HCodeType;
typedef struct {
	char s;
	int num;
} Message;
//哈夫曼树的构造算法
void HuffmanTree(HNodeType HuffNode[],int n,Message a[]) {
	int i,j,m1,m2,x1,x2,temp1;
	char temp2;
	for(i=0; i<2*n-1; i++) { //HuffNode[]初始化
		HuffNode[i].letter=NULL;
		HuffNode[i].weight=0;
		HuffNode[i].parent=-1;
		HuffNode[i].lchild=-1;
		HuffNode[i].rchild=-1;
	}
	for(i=0; i<n-1; i++)
		for(j=i+1; j<n-1; j++)
			if(a[j].num>a[i].num) {
				temp1=a[i].num;
				a[i].num=a[j].num;
				a[j].num=temp1;
				temp2=a[i].s;
				a[i].s=a[j].s;
				a[j].s=temp2;
			}
	for(i=0; i<n; i++) {
		HuffNode[i].weight=a[i].num;
		HuffNode[i].letter=a[i].s;
	}
	for(i=0; i<n-1; i++) { //构造哈夫曼树
		m1=m2=MAXVALUE;
		x1=x2=0;
		for(j=0; j<n+i; j++) { //找出的两棵权值最小的子树
			if(HuffNode[j].parent==-1&&HuffNode[j].weight<m1) {
				m2=m1;
				x2=x1;
				m1=HuffNode[j].weight;
				x1=j;
			} else if(HuffNode[j].parent==-1&&HuffNode[j].weight<m2) {
				m2=HuffNode[j].weight;
				x2=j;
			}
		}
		//将找出的两棵子树合并为一棵子树
		HuffNode[x1].parent=n+i;
		HuffNode[x2].parent=n+i;
		HuffNode[n+i].weight=HuffNode[x1].weight+HuffNode[x2].weight;
		HuffNode[n+i].lchild=x1;
		HuffNode[n+i].rchild=x2;
	}
}
//生成哈夫曼编码
void HuffmanCode(int n,Message a[]) {
	HNodeType HuffNode[MAXNODE];
	HCodeType HuffCode[MAXLEAF],cd;
	int i,j,c,p;
	char code[30],*m;
	HuffmanTree(HuffNode,n,a);//建立哈夫曼树
	for(i=0; i<n; i++) { //求每个叶子结点的哈夫曼编码
		cd.start=n-1;
		c=i;
		p=HuffNode[c].parent;
		while(p!=-1) { //由叶结点向上直到树根
			if(HuffNode[p].lchild==c)
				cd.bit[cd.start]=0;
			else
				cd.bit[cd.start]=1;
			cd.start--;
			c=p;
			p=HuffNode[c].parent;
		}
		for(j=cd.start+1; j<n; j++) //保存求出的每个叶结点的哈夫曼编码和编码的起始位
			HuffCode[i].bit[j]=cd.bit[j] ;
		HuffCode[i].start=cd.start;
	}
	printf("输出每个叶子的哈夫曼编码:\n");
	for(i=0; i<n; i++) { //输出每个叶子结点的哈夫曼编码
		HuffCode[i].letter=HuffNode[i].letter;
		printf("%c",HuffCode[i].letter);
		for(j=HuffCode[i].start+1; j<n; j++)
			printf("%d",HuffCode[i].bit[j]);
		printf("\n");
	}
	printf("请输入电文(1/0):\n");
	for(i=0; i<30; i++)code[i]=NULL;
	scanf("%s",&code);
	m=code;
	c=2*n-2;
	printf("输出哈夫曼译码:\n");
	while(*m!=NULL) {
		if(*m=='0') {
			c=i=HuffNode[c].lchild;
			if(HuffNode[c].lchild==-1&&HuffNode[c].rchild==-1) {
				printf("%c",HuffNode[i].letter);
				c=2*n-2;
			}
		}
		if(*m=='1') {
			c=i=HuffNode[c].rchild;
			if(HuffNode[c].lchild==-1&&HuffNode[c].rchild==-1) {
				printf("%c",HuffNode[i].letter);
				c=2*n-2;
			}
		}
		m++;
	}
	printf("\n");
}
int main() {
	Message data[30];
	char s[100],*p;
	int i,count=0;
	printf("\n 请输入一些字符:");
	scanf("%s",&s);
	for(i=0; i<30; i++) {
		data[i].s=NULL;
		data[i].num=0;
	}
	p=s;
	while(*p) {
		for(i=0; i<=count+1; i++) {
			if(data[i].s==NULL) {
				data[i].s=*p;
				data[i].num++;
				count++;
				break;
			} else if(data[i].s==*p) {
				data[i].num++;
				break;
			}
		}
		p++;
	}
	printf("\n");
	printf("不同的字符数:%d\n",count);
	for(i=0; i<count; i++) {
		printf("%c",data[i].s);
		printf("权值:%d",data[i].num);
		printf("\n");
	}
	HuffmanCode(count,data);
	getch();
}

Guess you like

Origin blog.csdn.net/weixin_54474126/article/details/122023577