Huffman树的应用 (数据结构)

Huffman树的应用:

1、先选择一篇文章

2、然后统计字符个数

3、对个数不为0字符的进行编码

4、输出码文

5、进行译码

上机代码:

/*************************************************************************
	> File Name: Huffman树的应用.cpp
	> Author: zzuspy
	> Mail: [email protected]
	> Created Time: 2014年12月3日 14:30
 ************************************************************************/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#define LL long long
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
using namespace std;

typedef struct
{
	int weight;
	int parent, lchild, rchild;
}HTNode, *HuffmanTree;

typedef char * * HuffmanCode;

int s1, s2;
void Select(HuffmanTree &HT, int n)
{
	int i, min;
	for(int i=1; i<=n; i++)
	{
		if(HT[i].parent==0)
		{
			min = i;
			break;
		}
	}
	for(i=1; i<=n; i++)
	{
		if(HT[i].weight<HT[min].weight && HT[i].parent == 0)min = i;
	}
	s1 = min;
	for(int i=1; i<=n; i++)
	{
		if(HT[i].parent==0 && i!=s1)
		{
			min = i;
			break;
		}
	}
	for(int i=1; i<=n; i++)
	{
		if(HT[i].parent == 0 && i!=s1 && HT[i].weight<HT[min].weight && HT[i].weight>=HT[s1].weight) min=i;
	}
	s2 = min;
}

void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
	if(n<=1) return;
	int m = 2 * n - 1, i;
	HuffmanTree p;
	HT = (HuffmanTree)malloc( (m + 1) * sizeof(HTNode));
	for( p = HT+1, i = 1; i <= n; i++, p++, w++)
	{
		p->weight = *w;
		p->parent = p->lchild = p->rchild = 0;
	}
	for(; i <= m; i++, p++)
	{
		p->weight = p->parent = p->lchild = p->rchild = 0;
	}

	//输出这时Huffman树
	/*for(int i=1; i<=n; i++)
	{
		printf("%d %d %d %d\n", HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
	}*/

	for(i = n + 1; i<=m; i++)
	{
		Select(HT, i-1);
		//printf("%d %d\n", s1, s2);
		HT[s1].parent = i; HT[s2].parent = i;
		HT[i].lchild = s1; HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}

	HC = (HuffmanCode)malloc( ( n + 1 ) * sizeof(char *));
	char *cd = (char *)malloc( n * sizeof(char) );
	cd[n-1] = '\0';
	for(i=1; i<=n; i++)
	{
		int start = n - 1;
		for(int c = i, f = HT[i].parent; f!=0; c=f, f=HT[f].parent)
			if(HT[f].lchild == c)  cd[--start] = '0';
			else cd[--start] = '1';
		HC[i] = (char*)malloc( (n-start) * sizeof(char));
		strcpy(HC[i], &cd[start]);
	}
	free(cd);
}

void mawen(HuffmanCode &HC, char str[])
{
	printf("\n\n");
	FILE *p;
	char c;
	p = fopen("essay","r");
	while((c = fgetc(p))!=EOF)
	{
		for(int i=0; str[i]!='\0'; i++)
		{
			if(str[i] == c)
			{
				printf("%c %s ", c, HC[i+1]);
				break;
			}
		}
	}
	fclose(p);
	printf("\n\n");
}

void codetext(char wen[], HuffmanCode &HC, char str[])
{
	int start = 0;
	FILE *p;
	char c;
	p = fopen("essay","r");
	while((c = fgetc(p))!=EOF)
	{
		for(int i=0; str[i]!='\0'; i++)
		{
			if(str[i] == c)
			{
				strcpy(wen+start, HC[i+1]);
				start+=strlen(HC[i+1]);
				break;
			}
		}
	}
	fclose(p);
	printf("\n\n");
}

void translate(char wen[], int wei[], char str[], HuffmanTree &HT, HuffmanCode &HC,  int elem)
{
	int q = 2 * elem - 1, n=0;
	char *ch;
	ch = (char*)malloc(100*sizeof(char));
	for(int i=0; wen[i]!='\0'; i++)
	{
		if(wen[i] == '0')
		{
			*(ch+n) = '0';
			*(ch+n+1) = '\0';
			n++;
			q = HT[q].lchild;
			if(HT[q].rchild==0 && HT[q].lchild==0)
			{
				int i;
				for(i=0; i<elem; i++)
				{
					if(!strcmp(ch, HC[i+1]))break;
				}
				printf("%c", str[i]);
				q = 2 * elem - 1;
				n = 0;
			}
		}
		else if(wen[i] == '1')
		{
			*(ch+n) = '1';
			*(ch+n+1) = '\0';
			n++;
			q = HT[q].rchild;
			if(HT[q].rchild==0 && HT[q].lchild==0)
			{
				int i;
				for(i=0; i<elem; i++)
				{
					if(!strcmp(ch, HC[i+1]))break;
				}
				printf("%c", str[i]);
				q = 2 * elem - 1;
				n = 0;
			}
		}
	}
}

int wei[128];        //保存字符数大于0的每个字符的数目 (即权值)
char str[128];      //保存字符数大于0的字符
int elem = 0;     //统计后字符数大于0的字符的总数
int statis[128];    //统计文章中各种字符的数目 

char wen[1000010];     //用于保存码文 

int main()
{
	//打开文件读取字符,再统计每个字符的个数
	FILE *p;
	char c;
	p = fopen("essay","r");
	while((c = fgetc(p))!=EOF)
	{
		printf("%c", c);      //输出文章
		statis[c]++;
	}
	fclose(p); 

	//输出统计后个数大于0的字符
	/*for(int i=0; i<128; i++)
	{
		if(statis[i]!=0)
		printf("%c : %d  ", i, statis[i]);
	}*/

	//压缩字符,去掉字符数为0的字符
	for(int i=0; i<128; i++)
	{
		if(statis[i]!=0)
		{
			str[elem] = i;
			wei[elem] = statis[i];
			elem++;
		}
	}

	//输出压缩后字符及其个数
	/*for(int i=0; i<elem; i++)
	{
		printf("%c : %d  ", str[i], wei[i]);
	}*/

	//printf("\n%d\n", elem);   //个数大于0的字符总数 

	HuffmanTree HT;
	HuffmanCode HC;
	//调用Huffman函数 ,将每个字符对应的编码存在HC里,HT为你所建立的Huffman树
	HuffmanCoding(HT, HC, wei, elem);

	//输出构造的Huffman树
	/*for(int i=1; i<=2*elem-1; i++)
	{
		printf("%d %d %d %d %d\n", i, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
	}*/

	//输出个数大于0的字符及其字符编码
	/*for(int i=1; i<=elem; i++)
	{
		printf("\n%c %s\n", str[i-1], HC[i]);
	}*/

	printf("\n\n"); 

	//调用码文函数
	mawen(HC, str);

	printf("\n\n"); 

	//生成码文
	codetext(wen, HC, str);
	//printf("%s\n", wen); 

	//译文
	translate(wen, wei, str, HT, HC, elem); 

	return 0;
}
时间: 2024-10-05 23:19:18

Huffman树的应用 (数据结构)的相关文章

数据结构之Huffman树与最优二叉树

最近在翻炒一些关于树的知识,发现一个比较有意思的二叉树,huffman树,对应到离散数学中的一种名为最优二叉树的路径结构,而Huffman的主要作用,最终可以归结到一种名为huffman编码的编码方式,使用huffman编码方式,我们可以以平均长度最短的码字来记录一串信息,且每个信息分子的编码唯一,独立.从而最终合成编码所对应的信息唯一,无歧义. huffman树的创建时基于每个信息分子都拥有其权重,权重越大,越靠近树根,即路径越短, 下面我们我们来以一个huffman树的例子为例:简单引入一下

【数据结构】Huffman树

参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊 考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小再找第二小的方法了. #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct{ unsigned int weight; unsigned int parent, lchild, r

数据结构之huffman树

#include <stdio.h> #include<stdlib.h> #define MAXBIT      99 #define MAXVALUE  9999 #define MAXLEAF     30 #define MAXNODE    MAXLEAF*2 -1 typedef struct  {     int bit[MAXBIT];     int start; } HCodeType;        /* 编码结构体 */ typedef struct {  

数据结构复习之利用Huffman树进行编码和译码

//编码#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<fstream> #include<map> using namespace std; typedef struct HuffmanNode{ int w;//节点的权值

数据结构C++使用最小堆实现huffman树

#pragma once #include"Heap.h"//使用博客实现的堆 template<class T> struct HuffmanNode//节点的结构信息 { T _weight; HuffmanNode<T>* _parent; HuffmanNode<T>* _left; HuffmanNode<T>* _right; HuffmanNode(const T& weight) :_weight(weight)

6月11日数据结构——Huffman树

对于Huffman树最终该输出什么不清楚 #include<stdio.h> #include<stdlib.h> #define leafNumber 20 //默认权值集合大小 #define totalNumber 39 //数结点个数=2*leafNumber-1 typedef struct { char data; //结点的值 int weight; //结点的权 int Parent,lchild,rchild; //双亲.左.右子女结点指针 }HTNode; ty

哈夫曼 (Huffman) 树的动画演示

 哈夫曼 (Huffman) 树的动画演示: http://people.cs.pitt.edu/~kirk/cs1501/animations/Huffman.html 此网站中亦有诸多其它算法的动画演示,可供学习算法或是数据结构相关内容时参考.

HUFFMAN 树

在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么是哈夫曼树.哈夫曼树又称最优二叉树, 是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点 的权值乘上其到根结点的 路径长度(若根结点为0层,叶结点到根结点的路径长度 为叶结点的层数).树的带权路径长度记为WPL= (W1*L1+W2*L2+W3*L3+...+Wn*Ln) ,

POJ 3253 Fence Repair (贪心 + Huffman树)

Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 28155   Accepted: 9146 Description Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000)