数据结构-哈夫曼树

一.什么是哈夫曼树

不同搜索树的效率是不一样的,根据不同的频率构造效率比较好或者最好的搜索树就是哈夫曼树

二.哈夫曼树的定义

将带权路径的长度降低最低

每个叶子节点到根节点的距离乘权值,再全都加起来就得到了WPL值

第一颗二叉树:从上到下计算 5x1+4x2+3x3+2x4+1x4=34

第二颗二叉树:从上到下计算 1x1+2x2+3x3+4x4+5x4=50

第二颗二叉树:从上到下计算 1x3+2x3+3x2+4x2+5x2=33

哈夫曼树为了构造一个树WPL最小

三.哈夫曼树的构造

构造哈夫曼树的方法从小到大排序,将最小的两个权值并在一起形成新的二叉树,这个二叉树的权值就是并在一起两个权值的和,再把这个根形成的根节点放到序列中重新按照从小到大排序,然后重复上面的操作,直到所有节点都用完

下面的列子权值 (1,2,3,4,5,6)

实现哈夫曼树的代码

把节点权值构造成最小堆,从里面找出两个最小和在一起形成一个新的节点在插入到堆中,也可以用排序的方法但不如堆的效率高.

cpp 复制代码
#include<iostream>
using namespace std;
typedef struct HNode* Heap;
typedef struct TreeNode* HuffmanTree;
typedef HuffmanTree ElementType;
int A[] = { 13,1,45,7,20,4,19,13,40,33,38 };  // 预先定义好一组权值 
int A_length = 11;  // 定义其长度 
struct TreeNode
{
	int Weight;//权值
	HuffmanTree Left, Right;//左右孩子
};
struct HNode {
	ElementType* Data;//存储哈夫曼的数组
	int Size;//当前堆元素的个数
	int Capacity;//堆的最大容量
};
HuffmanTree CreateHuffman() {
	HuffmanTree Huffman = new TreeNode();
	Huffman->Weight = 0;
	Huffman->Right = Huffman->Left = NULL;
	return Huffman;
}
typedef Heap MinHeap;//最小堆
#define MINDATA -1000;
MinHeap CreateHeap(int MaxSize) {
	//创建容量为MinSize的空的最小堆
	MinHeap H = new HNode();
	H->Data = new ElementType[MaxSize + 1];
	H->Size = 0;
	H->Capacity = MaxSize;
	HuffmanTree man = CreateHuffman();
	man->Weight = MINDATA;
	H->Data[0] = man;
	return H;
}

bool Insert(MinHeap H, ElementType X) {
	int i;
	i = ++H->Size;/*增加树的元素*/
	/*根节点元素大于插入的元素根节点元素从根节点到子节点*/
	for (; H->Data[i / 2]->Weight > X->Weight; i /= 2)
		H->Data[i] = H->Data[i / 2];/*根节点下来*/
	H->Data[i] = X;
	return true;
}

ElementType DeleteMin(MinHeap H) {
	int Parent, Child;
	ElementType MinHuffman, X;
	MinHuffman= H->Data[1];//取出根节点存放的最小值
	X = H->Data[H->Size--];//取出堆最后一个值并删除
	/*Parent*2<=H->Size判断左子树是否存在
	Parent*2>H->Size 表示左字数不存在*/
	for (Parent = 1; Parent * 2 <= H->Size; Parent = Child) {/*向下到左右树最小的地方*/
		Child = Parent * 2;
		/*Child!=H->Size判断右子树是否存在,
		左子树等于Size表明左子树是最后一个元素
		所以右子树不存在*/
		if ((Child != H->Size) && (H->Data[Child + 1]->Weight < H->Data[Child]->Weight))
			Child++;
		if (H->Data[Child]->Weight >= X->Weight)break;
		else
			/*左右儿子中最小的值上来*/
			H->Data[Parent] = H->Data[Child];
	}
	H->Data[Parent] = X;
	return MinHuffman;
}
void PercDown(MinHeap H, int p) {
	int Parent, Child;
	ElementType X;
	X = H->Data[p];//取出根节点
	for (Parent = p; Parent * 2 <= H->Size; Parent = Child) {
		Child = Parent * 2;
		if ((Child != H->Size) && (H->Data[Child + 1]->Weight < H->Data[Child]->Weight))
			Child++;
		if (H->Data[Child]->Weight >= X->Weight)
			break;
		else
			H->Data[Parent] = H->Data[Child];
	}
	H->Data[Parent]->Weight = X->Weight;
}
void BuildHeap(MinHeap H) {
	/*调整H->Data[]中的元素,使满足小堆的有序性*/
	/*这里假设所有H->Size个元素已经存在H->Data[]中*/
	/*从最后一个节点的父节点开始,到根节点1*/
	int i;
	for (i = H->Size / 2; i > 0; i--)
		PercDown(H, i);
}
void BuildMinHeap(MinHeap H) {
	HuffmanTree Huff;
	for (int i = 0; i < A_length; i++) {
		Huff = CreateHuffman();
		Huff->Weight = A[i];
		H->Data[++H->Size] = Huff;
	}
	BuildHeap(H);
}
//遍历 
void PreOrderTraversal(HuffmanTree Huff) {
	if (Huff) {
		cout << Huff->Weight << " ";
		PreOrderTraversal(Huff->Left);
		PreOrderTraversal(Huff->Right);
	}
}
HuffmanTree Huffman(MinHeap H) {
	HuffmanTree T;
	BuildMinHeap(H);
	int times = H->Size;
	for (int i = 1; i < times; i++) {
		T = new TreeNode();
		T->Left = DeleteMin(H);
		T->Right = DeleteMin(H);
		T->Weight = T->Right->Weight + T->Left->Weight;
		Insert(H, T);
	}
	T = DeleteMin(H);
	return T;
}
int main()
{
	MinHeap H;
	HuffmanTree Huff;
	H = CreateHeap(1000);
	Huff = Huffman(H);
	PreOrderTraversal(Huff);
	return 0;
	
}

四.哈夫曼树的特点

1.特点没有度唯1的节点因为每个节点都是两个权值合并在一起形成的

五.哈夫曼编码

当所有的节点都在叶节点就不可能出现一个字符编码是另一个字符的前缀,当你编码节点出现在另外一个编码节点当中的时候在树的非叶节点上的时候会场出现前缀

相关推荐
用户00993831430139 分钟前
代码随想录算法训练营第十三天 | 二叉树part01
数据结构·算法
shinelord明43 分钟前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
薄荷故人_1 小时前
从零开始的C++之旅——红黑树及其实现
数据结构·c++
努力学习编程的伍大侠1 小时前
基础排序算法
数据结构·c++·算法
XiaoLeisj2 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jackey_Song_Odd3 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
乐之者v3 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A4 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
️南城丶北离5 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
✿ ༺ ོIT技术༻5 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++