哈夫曼树(Huffman tree)->一种二叉树
2017-01-22 17:57
597 查看
知识前提:
一棵树的路径长度为从树根到其余各节点的路径长度之和
结点的带权路径长度为从根结点到该结点之间的路径长度与该结点上所带权值的乘积
每个叶结点的带权路径长度之和就是这棵树的带权路径长度
哈夫曼树定义:
假设有n个权值,构造有n个叶子的二叉树,每个叶子的权值就是n个权值之一,这样可以构造很多个,其中一个是带权路径长度最小的,这棵二叉树就被称为哈夫曼树或最优二叉树
哈夫曼树的构造,用到最小堆:
必须使权值越大的叶结点越靠近根节点,提出一种贪心算法,在初始状态下,将每个元素看作一棵独立的树,每次选择权值最小的两棵树进行合并
对于同一组给定权值叶结点所构造的哈夫曼树,树的形状可能不同。但无论形状如何,这些哈夫曼树的带权路径长度是相同的,并且一定都是同一最小值
应用:哈夫曼编码
又称“前缀编码”,为了不产生二义性,任何一个字符的编码都不能是另一个字符编码的前缀
一棵树的路径长度为从树根到其余各节点的路径长度之和
结点的带权路径长度为从根结点到该结点之间的路径长度与该结点上所带权值的乘积
每个叶结点的带权路径长度之和就是这棵树的带权路径长度
哈夫曼树定义:
假设有n个权值,构造有n个叶子的二叉树,每个叶子的权值就是n个权值之一,这样可以构造很多个,其中一个是带权路径长度最小的,这棵二叉树就被称为哈夫曼树或最优二叉树
哈夫曼树的构造,用到最小堆:
必须使权值越大的叶结点越靠近根节点,提出一种贪心算法,在初始状态下,将每个元素看作一棵独立的树,每次选择权值最小的两棵树进行合并
对于同一组给定权值叶结点所构造的哈夫曼树,树的形状可能不同。但无论形状如何,这些哈夫曼树的带权路径长度是相同的,并且一定都是同一最小值
#include <cstdio> #include <cstring> #include <iostream> using namespace std; struct node{ int weight; struct node *left; struct node *right; }; void PercolateDown(struct node *minHeap[],int loc,int *n){ int i,child; struct node *temp=minHeap[loc]; for(i=loc;i*2<=*n;i=child){ child=i*2; if(child+1<=*n&&minHeap[child+1]->weight<minHeap[child]->weight) child++; if(temp->weight>minHeap[child]->weight) minHeap[i]=minHeap[child]; else break; } minHeap[i]=temp; } void PercolateUp(struct node *minHeap[],int loc){ int i; struct node *temp=minHeap[loc]; for(i=loc;i>1;i/=2){ if(minHeap[i/2]->weight>minHeap[i]->weight) minHeap[i]=minHeap[i/2]; else break; } minHeap[i]=temp; } struct node *DeleteMin(struct node *minHeap[],int *n){ struct node *temp=minHeap[1]; minHeap[1]=minHeap[(*n)--]; PercolateDown(minHeap,1,n); return temp; } void Insert(struct node *minHeap[],struct node *temp,int *n){ minHeap[++(*n)]=temp; PercolateUp(minHeap,*n); } void BuildHeap(struct node *minHeap[],int *n){ for(int i=*n/2;i>=1;i--){ PercolateDown(minHeap,i,n); } } struct node *BuildHuffman(struct node *minHeap[],int *n){ int t=*n; struct node *temp,*Huffman; for(int i=1;i<t;i++){ temp=(struct node *)malloc(sizeof(struct node)); temp->left=DeleteMin(minHeap,n); temp->right=DeleteMin(minHeap,n); temp->weight=temp->left->weight+temp->right->weight; Insert(minHeap,temp,n); } return DeleteMin(minHeap,n); } void InOrderTraversal(struct node *Huffman){ if(Huffman==NULL) return; InOrderTraversal(Huffman->left); cout<<' '<<Huffman->weight; InOrderTraversal(Huffman->right); } int main(){ int size,temp; struct node *minHeap[100]; struct node *Huffman; cin>>size; for(int i=1;i<=size;i++){ cin>>temp; minHeap[i]=(struct node *)malloc(sizeof(struct node)); minHeap[i]->weight=temp; minHeap[i]->left=NULL; minHeap[i]->right=NULL; } BuildHeap(minHeap,&size); Huffman=BuildHuffman(minHeap,&size); InOrderTraversal(Huffman); return 0; }
应用:哈夫曼编码
又称“前缀编码”,为了不产生二义性,任何一个字符的编码都不能是另一个字符编码的前缀
相关文章推荐
- 6-9-哈夫曼树(HuffmanTree)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版
- 数据结构.哈夫曼树(HuffmanTree)
- Binary Tree Level Order Traversal,层序遍历二叉树,每层作为list,最后返回List<list>
- (哈夫曼树)HuffmanTree的java实现
- 二叉树的创建--(2)运算符重载<<、>>以及CreateBinaryTree、Traverse、PrintBTree函数
- <leetcode> 105. Construct Binary Tree from Preorder and Inorder Traversal 重建二叉树
- 数据结构基础5.5:哈夫曼树(HuffmanTree)的构造
- 哈夫曼树(Huffman Tree) 实现
- 哈夫曼树(Huffman Tree)
- Codeforces 383C. Propagating tree(树上hash映射+线段树懒操作)->(一种将树结点规律化的方法)
- 1102. Invert a Binary Tree (25)<反转二叉树>
- 哈夫曼树(Huffman Tree)与哈夫曼编码
- 树-哈夫曼树(Huffman Tree)
- Java实现哈夫曼树(HuffmanTree)
- 哈夫曼树 Huffman tree 原理
- Huffman tree(赫夫曼树、霍夫曼树、哈夫曼树、最优二叉树)
- 【Java】二叉树(Binary Tree)重温
- 动态查找---->B树(broad-tree 平衡多路查找树)
- 6_7 树的层次遍历(UVa122)<二叉树的动态创建与BFS>
- 哈夫曼树(haffman tree)的某题