Huffman编码的C++高效实现

326 篇文章 2 订阅
85 篇文章 2 订阅

Huffman编码算法可用于文字压缩或加密解密

采用C++语言给出其高效实现,读者可思考实现算法中指针用法和树的构建过程

代码如下:

//Huffman  algorithm demo
//本算法主要掌握树的构建过程,尤其,掌握指针的使用方法
//author: Liping chen
//email: alaclp@qq.com
//published date: 2015-4-7

#include <iostream>
#include <string>

using namespace std;

//定义树类型————认为最小的树是一个节点
typedef struct Tree {
	int val;
	int times;
	Tree *left, *right, *parent, *next;  //如果使用了next,则认为是森林

	//构造函数
	Tree() : val(-1), times(0), left(NULL), right(NULL), parent(NULL), next(NULL) {}
	Tree(int val, int times) : val(val), times(times), left(NULL), right(NULL), 
			parent(NULL), next(NULL) {}

	//递归输出树的叶子节点
	void output() {
		Tree *ptr = this;
		string info;
		//根节点,输出总信息
		if (parent == NULL) cout << "Huffman编码方案:" << endl;
		if (val != -1) {    //叶子节点
			while(ptr->parent) {
				info += (ptr->parent->left == ptr) ? "0":"1";
				ptr = ptr->parent;
			}
			cout << (char)val << "[" << times << "]=" << info << endl;
		}
		else {   //非叶子节点
			if (left) left->output();
			if (right) right->output();
		}		
	}

	//析构函数
	~Tree() {
		if (left) delete left;
		if (right) delete right;
		//cout << "delete :" << val << "(times: " << times << ")" << endl;
	}
} Tree;


//定义森林类或多棵树的类
typedef struct Trees {
	Tree *head, *tail;   //头树,尾树指针

	//向森林里添加树
	void addTree(Tree *tree) {
		if (head == NULL) {
			head = tail = tree;
			return;
		}
		Tree *ptr = head, *last = NULL;
		bool inserted = false;
		while(ptr) {
			if (ptr->times > tree->times) {
				if (last == NULL) {
					tree->next = head;
					//tail = head;
					head = tree;					
				}
				else {
					last->next = tree;
					tree->next = ptr;
				}
				inserted = true;
				break;
			}
			last = ptr;
			ptr = ptr->next;
		}
		if (!inserted) {
			last->next = tree;
			tail = tree;
			tree->next = NULL;
		}
	}

	//构造函数——利用字母和其统计次数,构造森林
	Trees(int vals[], int times[], int n) : head(NULL), tail(NULL) {
		Tree *tree;
		//动态创建树,并加入森林
		for(int i = 0; i < n; i++) {
			tree = new Tree(vals[i], times[i]);
			addTree(tree);   //添加树到森林并按times排序
		}
		//
		while(head->next != NULL) {
			outputTrees();
			Tree *t1 = head, *t2 = t1->next;
			tree = new Tree(-1, t1->times + t2->times);
			tree->left = t1;
			tree->right = t2;
			head = t2->next;
			tree->left->next = NULL;
			tree->right->next = NULL;
			tree->left->parent = tree;
			tree->right->parent = tree;
			addTree(tree);
		}
		outputTrees();
	}

	//编写output类辅助方法用于观察程序中间结果以调试程序
	//用于输出森林————多棵树间的next关系遍历
	void outputTrees() {
		Tree *ptr = head;
		cout << "森林:";
		while(ptr) {
			cout << (char)(ptr->val) << "[" << ptr->times << "] ";
			ptr = ptr->next;
		}
		cout << endl;
	}
	
	//输出huffman编码
	void output() {
		head->output();
	}

	~Trees() {
		delete head;
	}
} Trees;

int main()
{
	int vals[] = {'a', 'b', 'c', 'd', 'e', 'f'};
	int times[] = {45, 13, 12, 16, 9, 5};
	Trees trees(vals, times, 6);
	trees.output();
	return 0;
}

程序运行结果:

~$ ./a.out
森林:f[5] e[9] c[12] b[13] d[16] a[45]
森林:c[12] b[13] �[14] d[16] a[45]
森林:�[14] d[16] �[25] a[45]
森林:�[25] �[30] a[45]
森林:a[45] �[55]
森林:�[100]
Huffman编码方案:
a[45]=0
c[12]=001
b[13]=101
f[5]=0011
e[9]=1011
d[16]=111


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值