huffman树入门
这段代码是对数学结构课本上的huffman树的一个简单优化。基本操作不变,对于一些错误进行了更正。并且化繁为简,改掉了一些冗长的代码。并且在个别地方进行修改,且对重要之处加以注释,以增强代码的可读性。配了一张自己做的小图。
参考书目《数据结构(c语言版)》中国水利水电出版社 主编:赵坚
#include "stdio.h" #include "stdlib.h" #define m 100 typedef struct ptree /*包含权值,左右子树的二叉树结构*/ { int weight; struct ptree *lchild,*rchild; }pTree; typedef struct pforest /*以二叉树为成员的森林结构*/ { struct pforest *link; pTree *root; }pForest; int WPL=0; pForest *inforest(pForest *f,pTree *t) /*将树从小到大排序组成森林*/ { pForest *q,*p,*r; pTree *pt; r=(pForest *)malloc(sizeof(pForest)); r->root =t; q=f; p=f->link ; while(p!=NULL) /*寻找插入位置,每次保证从小到大*/ { pt=p->root ; if(t->weight >pt->weight ) { q=p; p=p->link ; } else break; /*为了使循环终止*/ /*p=NULL; 也可以。 p=NULL并不会对原来的森林结构造成影响,p只是个指针*/ } r->link =q->link ; q->link =r; return f; } pTree *hufm(int n,int w[m]) { pForest *p1,*p2,*f; pTree *t1,*t2,*t,*pt; int i; f=(pForest *)malloc(sizeof(pForest)); f->link =NULL; for(i=1;i<=n;i++) /*产生n棵只有根结点的二叉树*/ { pt=(pTree *)malloc(sizeof(pTree)); /*开辟新的结点空间*/ pt->weight =w[i]; /*对结点赋权值*/ pt->lchild =NULL; /*指针初始化为空*/ pt->rchild =NULL; f=inforest(f,pt); } while((f->link )->link !=NULL) { p1=f->link ; p2=p1->link; f->link =p2->link ; t1=p1->root ; t2=p2->root ; free(p1); free(p2); t=(pTree *)malloc(sizeof(pTree)); t->weight =t1->weight +t2->weight ; t->lchild =t1; t->rchild =t2; f=inforest(f,t); } /*以下操作彻底删除森林结构的痕迹,因为haffman树已经成型*/ p1=f->link ; t=p1->root ; free(f); return(t); } void travel(pTree *head,int n) /*先序遍历huffman树*/ { pTree *p; p=head; if(p!=NULL) { if(p->lchild ==NULL&&p->rchild ==NULL) { printf("结点权值为%d的路径长度为:%d\n",p->weight ,n); WPL=WPL+n*(p->weight ); /*计算权值*/ } travel(p->lchild ,n+1); travel(p->rchild ,n+1); } } int main() { pTree *head; int n; int i,w[m]; printf("请输入结点总数\n"); scanf("%d",&n); printf("请输入每个结点的权值\n"); for(i=1;i<=n;i++) scanf("%d",&w[i]); head=hufm(n,w); travel(head,0); printf("最佳路径的权值之和为%d\n",WPL); }