数据结构—哈夫曼树
2016-06-01 21:32
411 查看
/* 哈夫曼树。 */ #include <iostream> #include <malloc.h> #define M 2*N-1 #define N 50 typedef char ElemType; using namespace std; typedef struct { char data; //节点值 double weight; //权值 int parent; //双亲节点 int lchild; //左孩子节点 int rchild; //右孩子节点 } HTNode; typedef struct { char cd ; //存放当前节点的哈夫曼编码 int start; //cd[start]~cd 存放哈夫曼编码 }HCode; /* 算法思路: 先将所有2n-1个节点的parent、lchild和rchild域置为初值-1,处理每个非叶子节点ht[i]: 从ht[0]~ht[i-1]中找出根节点权值最小的两个,将它们作为ht[i]的左右子树,并将它们两个的双亲节点置为ht[i], 并且ht[i]的权值为它们两个权值之和。如此操作,直到所有n-1个非叶子节点处理完毕。 */ void CreateHT(HTNode ht[],int n) { int i,k,lnode,rnode; double min1,min2; for (i=0; i<2*n-1; i++) //所有结点的相关域置初值-1 ht[i].parent=ht[i].lchild=ht[i].rchild=-1; for (i=n; i<2*n-1; i++) //构造哈夫曼树 { min1=min2=32767; //lnode和rnode为最小权重的两个结点位置 lnode=rnode=-1; for (k=0; k<=i-1; k++) if (ht[k].parent==-1) //只在尚未构造二叉树的结点中查找 { if (ht[k].weight<min1) { min2=min1; rnode=lnode; min1=ht[k].weight; lnode=k; } else if (ht[k].weight<min2) { min2=ht[k].weight; rnode=k; } } ht[i].weight=ht[lnode].weight+ht[rnode].weight; ht[i].lchild=lnode; ht[i].rchild=rnode; ht[lnode].parent=i; ht[rnode].parent=i; } } /* 以字符集合做叶子节点,以频率做权值构造哈夫曼树,规定哈夫曼树的左分支为0,右分支为1。 */ void CreateHCode(HTNode ht[],HCode hcd[],int n) { int i,f,c; HCode hc; for (i=0; i<n; i++) //根据哈夫曼树求哈夫曼编码 { hc.start=n; c=i; f=ht[i].parent; while (f!=-1) //循序直到树根结点 { if (ht[f].lchild==c) //处理左孩子结点 hc.cd[hc.start--]='0'; else //处理右孩子结点 hc.cd[hc.start--]='1'; c=f; f=ht[f].parent; } hc.start++; //start指向哈夫曼编码最开始字符 hcd[i]=hc; } } //输出哈夫曼编码 void DispHCode(HTNode ht[],HCode hcd[],int n) { int i,k; double sum=0,m=0; int j; cout<<" 输出哈夫曼编码:\n"; //输出哈夫曼编码 for (i=0; i<n; i++) { j=0; cout<<" "<<ht[i].data<<":\t"; for (k=hcd[i].start; k<=n; k++) { cout<<hcd[i].cd[k]; j++; } m+=ht[i].weight; sum+=ht[i].weight*j; cout<<endl; } cout<<"\n 平均长度="<<1.0*sum/m<<endl; } int main() { int n=8,i; //n表示初始字符串的个数 char str[]= {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; double fnum[]= {0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.1}; HTNode ht[M]; HCode hcd ; for (i=0; i<n; i++) { ht[i].data=str[i]; ht[i].weight=fnum[i]; } cout<<endl; CreateHT(ht,n); CreateHCode(ht,hcd,n); DispHCode(ht,hcd,n); cout<<endl; return 0; }
运行结果:
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)