哈夫曼树的简单实现(C语言)(西工大数据结构)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

哈夫曼树的简单实现(C语言)(西工大数据结构)
哈夫曼树
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。

哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

基本术语
哈夫曼树又称为最优树. 1、路径和路径长度在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。

通路中分支的数目称为路径长度。

若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。

2、结点的权及带权路径长度哈夫曼树若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。

结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

3、树的带权路径长度树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL
构造
典型的贪心算法假设有n个权值,则构造出的哈夫曼树有n 个叶子结点。

n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为: (1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点); (2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和; (3)从森林中删除选取的两棵树,并将新树加入森林; (4)重复(2)、(3)
步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

(百度图片真香)对于有n个叶子结点的哈夫曼树,结点总数为2n+1,即可将叶子结点集中到前面1到n个位置,
后面n-1个位置存储其余非叶子结点。

我们可以用一个静态三叉链表来存储。

注意注意!!函数使用时最好不要用地址传,直接引入就好,不然会出错,最好不用* 其实如稀疏矩阵,线性表(数组表示),哈夫曼树,此类有定义实际空间的其实不必要强用地址,反而会出步不要的错。

#include<stdio.h>#include<stdlib.h>#define N 30
#define M 2*N-1 typedefstruct{int weight;
int parent;
int Lchild;
int Rchild;
int flag;
}HTNode,HuffmanTree[M+1]; 复制代码
主程序如下:
#include<stdio.h>#include<stdlib.h>#define N 30
#define M 2*N-1 typedefstruct{int weight;
int parent;
int Lchild;
int Rchild;
int flag;
}HTNode,HuffmanTree[M+1]; intselect(HuffmanTree ht,int n);
voidInitHuffmanTree(HuffmanTree ht,int n); voidcrtHuffmanTree(HuffmanTree ht,int n); voidprintHuffmanTree(HuffmanTree ht,int n);
voidInitHuffmanTree(HuffmanTree ht,int n)
{
for(int i=1;i<=n;i++)
{
ht[i].Lchild=0;
ht[i].Rchild=0;
ht[i].weight=0;
ht[i].parent=0;
ht[i].flag=0;
scanf("%d",&ht[i].weight);
}
int m=2*n-1;
for(int i=n+1;i<=m;i++)
{
ht[i].Lchild=0;
ht[i].Rchild=0;
ht[i].weight=0;
ht[i].parent=0;
ht[i].flag=0;
}
}
voidcrtHuffmanTree(HuffmanTree ht,int n)
{
for(int i=n+1;i<=(2*n-1);i++)
{
int s1=select(ht,i-1);int s2=select(ht,i-1); ht[i].weight = ht[s1].weight+ht[s2].weight; ht[s1].parent=i;
ht[s2].parent=i;
ht[i].Lchild=s1;
ht[i].Rchild=s2;
}
}
intselect(HuffmanTree ht,int n)
{
int i,temp,min;
for(i=1;i<=n;i++)
{
if(ht[i].flag==0)
{
temp = ht[i].weight;
min=i;break;
}
}
for(i=1;i<=n;i++)
{
if(ht[i].flag==0&&temp>ht[i].weight)
{
temp=ht[i].weight;
min = i;
}
}
ht[min].flag=1;
return min;
}
voidprintHuffmanTree(HuffmanTree ht,int n)
{ printf("结点 weigh parent Lchild Rchild\n"); for(int i=1;i<=n;i++)
{printf("%d\t%d\t%d\t%d\t%d\n",i,ht[i].weight,ht[i].pa rent,ht[i].Lchild,ht[i].Rchild);
}
printf("\n");
}
intmain()
{
HuffmanTree ht;
int n;printf("输入所需创建的结点数为:");
scanf("%d",&n);
InitHuffmanTree(ht,n);printf("初始的哈夫曼树为
\n");
printHuffmanTree(ht,2*n-1);
crtHuffmanTree(ht,n);printf("构建后的哈夫曼树为\n");
printHuffmanTree(ht,2*n-1);return0;
}
复制代码
我要说的都在笔记里了,就不多写了。

相关文档
最新文档