数据结构(c)——赫夫曼树与赫夫曼编码
2016-05-03 20:03
591 查看
二叉树的一个重要应用——赫夫曼树(最优二叉树),即所有叶子结点的平均带权路径最短。
赫夫曼算法叙述如下:
(1)根据给定的n个权值{w1,w2,...wn}构成n棵二叉树的集合F={T1,,T2,...,Tn},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均空;
(2)在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和;
(3)在F中删除这两棵树,同时将新得到的二叉树加入F中;
(4)重复(2)和(3),直到F只含一棵树为止。这棵树便是赫夫曼树。
程序中赫夫曼用顺序存储结构,赫夫曼编码用二维数组。
定义结构体:
赫夫曼算法叙述如下:
(1)根据给定的n个权值{w1,w2,...wn}构成n棵二叉树的集合F={T1,,T2,...,Tn},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均空;
(2)在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和;
(3)在F中删除这两棵树,同时将新得到的二叉树加入F中;
(4)重复(2)和(3),直到F只含一棵树为止。这棵树便是赫夫曼树。
程序中赫夫曼用顺序存储结构,赫夫曼编码用二维数组。
定义结构体:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct HTNode{ unsigned int weight; unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char **HuffmanCode;定义函数以及主函数:
void Select(HuffmanTree HT,int n,int &S1,int &S2); void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n); main(){ HuffmanTree HT; HuffmanCode HC; int w[] = {2,3,1,4}; HuffmanCoding(HT,HC,w,4); printf("赫夫曼树\n"); for(int i = 1;i <= 7;i ++){ printf("%d,%d,%d,%d\n",HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); } printf("赫夫曼编码\n"); for(int i = 1;i <= 4;i ++){ printf("%s\n",HC[i]); } }实现HuffmanCoding函数,以及从赫夫曼树中选择两个权值最小的结点
void Select(HuffmanTree HT,int n,int &S1,int &S2){ // S1在前,S2在后 S1 = 0; S2 = 0; for(int i = 1;i <= n;i ++){ if(HT[i].parent == 0){ S1 = i; break; } } for(int i = 1;i <= n;i ++){ if(HT[i].parent == 0){ if(HT[i].weight < HT[S1].weight){ S1 = i; } } } //找到最小权值的下标 for(int i = 1;i <= n;i ++){ if(HT[i].parent == 0){ if(i != S1){ S2 = i; break; } } } for(int i = 1;i <= n;i ++){ if(HT[i].parent == 0){ if(HT[i].weight < HT[S2].weight && i != S1){ S2 = i; } } } //找到第二小权值的下标 if(S1 > S2){ int temp = S1; S1 = S2; S2 = temp; } } void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){ //w存在n个权值,构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC if(n <= 1) return; int m = 2 * n - 1; HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); //0号单元不用 int i; HuffmanTree p; for(p = HT + 1,i = 1;i <= n;++i,++p,++w) { p->weight = *w; p->parent = 0; p->lchild = 0; p->rchild = 0; } for(;i <= m;++i,++p){ p->weight = 0; p->parent = 0; p->lchild = 0; p->rchild = 0; } for(i = n+1;i <= m;i++){ //构造赫夫曼树 int S1,S2; //在HT[1,...,i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2. Select(HT,i - 1,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(int i = 1;i <= n;i ++){ //逐个求赫夫曼编码 int start = n - 1; //编码结束符位置 int c; int f; for(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]); //复制串到HC } free(cd); }运行结果:
相关文章推荐
- 超好的数据结构算法可视化网站
- 数据结构—快速排序模型
- 数据结构—顺序表—删除某个元素
- 源码分析redis的有序集合,学习skiplist跳跃表数据结构
- 数据结构与算法——无权最短路径算法的C++实现
- 图解程序员画流程图、数据结构图及各种复杂图形的Graphviz工具入门
- 数据结构与算法--求最大子列和问题
- 在线算法与数据结构
- 在线算法与数据结构
- 【数据结构】将有序数组转为二叉搜索树
- Python dict dictionaries Python 数据结构——字典
- 数据结构复习
- 数据结构与算法-内行看门道
- Java数据结构之快速排序
- 数据结构和算法
- 【数据结构】二叉树
- 数据结构--数组和ArrayList
- 【数据结构】 二叉树
- 数据结构之优先级队列(二叉堆)
- 常用树类数据结构总结-二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的性能分析