C++实现哈夫曼树简单创建与遍历的方法
本文以实例形式讲述了C++实现哈夫曼树简单创建与遍历的方法,比较经典的C++算法。
本例实现的功能为:给定n个带权的节点,如何构造一棵n个带有给定权值的叶节点的二叉树,使其带全路径长度WPL最小。
据此构造出最优树算法如下:
哈夫曼算法:
1.将n个权值分别为w1,w2,w3,....wn-1,wn的节点按权值递增排序,将每个权值作为一棵二叉树。构成n棵二叉树森林F={T1,T2,T3,T4,...Tn},其中每个二叉树都只有一个权值,其左右字数为空
2.在森林F中选取根节点权值最小二叉树,作为左右字数构成一棵新的二叉树,并使得新的二叉树的根节点为
其左右字数权值之和,其中叶子都是最初的树
3.在森林F中删除这两棵树,同时将新得到的二叉树代替这两个树加入到森林F中,因此森林中二叉树的个数比以前少一颗
4.对新的森林重复2和3,知道森林中只有一棵树位置,这棵树就是哈夫曼树.
#include<iostream> usingnamespacestd; #defineLEAFNUM10//叶子节点数,也就是权值树 #defineHUFNUM2*LEAFNUM #defineMAXWEIGHT999.9 //*********存储结构*********** classHufTree; //*****Node********** classNODE { private: charData;//节点的数据域 doubleWeight;//节点的权值域 intLchild,Rchild,Parent;//节点的左孩子右孩子及双亲域 public: NODE()//构造函数 { Data='\0'; Weight=0; Lchild=-1; Rchild=-1; Parent=-1;//给节点的数据初始化 } intRe_L(){returnLchild;} intRe_R(){returnRchild;} charRe_Data(){returnData;} doubleRe_Weight(){returnWeight;} friendclassHufTree;//声明友元 };//Node //********HufTree类********** classHufTree { private: intNodeNum; NODEHufArry[HUFNUM]; public: HufTree(){NodeNum=0;} voidSetHuf(int,double,char);//设置权值与数据域 voidCreatHuf();//创建哈夫曼树 voidSelectMin(int,int&,int&);//查找哈夫曼树种两个权值最小的树 voidFind_Root_and_Print();//查找树根节点位置 voidPrintHuf(int);//遍历哈夫曼树 };//huftree voidHufTree::SetHuf(inti,doublewei,charch) { HufArry[i].Data=ch; HufArry[i].Weight=wei; } voidHufTree::CreatHuf() { cout<<"每次查询两个最小树的位置:"<<endl; for(inti=LEAFNUM;i<HUFNUM-1;i++) { intp1=0; intp2=0; SelectMin(i,p1,p2);//找出当前树种权值最小的两颗树 cout<<p1<<"<->"<<p2<<endl; HufArry[p1].Parent=i;//设置两颗最小树的双亲 HufArry[p2].Parent=i; HufArry[i].Lchild=p1;//设置这棵3节点的树的根的权值以及孩子 HufArry[i].Rchild=p2; HufArry[i].Weight=HufArry[p1].Weight+HufArry[p2].Weight; } cout<<"************************"<<endl; } voidHufTree::SelectMin(inti,int&p1,int&p2) { intleast1=MAXWEIGHT; intleast2=MAXWEIGHT; for(intj=0;j<i;j++) { if(HufArry[j].Parent==-1) { if(HufArry[j].Weight<least1) { least2=least1; least1=HufArry[j].Weight; p2=p1; p1=j; } else { if(HufArry[j].Weight<least2) { least2=HufArry[j].Weight; p2=j; } } } } } voidHufTree::Find_Root_and_Print() { introot; for(inti=0;i<HUFNUM-1;i++) { if(HufArry[i].Parent==-1) { root=i; break; } } PrintHuf(root); } voidHufTree::PrintHuf(intposition) { if(NodeNum==LEAFNUM) { return; } else { if(HufArry[position].Data!='\0')//如果是叶子节点 { cout<<"权值:"<<HufArry[position].Weight<<"<->数据:"<<HufArry[position].Data<<"此节点为叶子"<<endl; NodeNum=NodeNum+1; } else { cout<<"权值:"<<HufArry[position].Weight<<"此节点无数据域,不是叶子"<<endl; PrintHuf(HufArry[position].Lchild); PrintHuf(HufArry[position].Rchild); } } } intmain() { HufTreeTree; cout<<"请输入"<<LEAFNUM<<"对(权值,数据):"<<endl; doublewei; charch; for(inti=0;i<LEAFNUM;i++) { cin>>wei; cin>>ch; Tree.SetHuf(i,wei,ch); } Tree.CreatHuf();//创建哈夫曼树 Tree.Find_Root_and_Print();//遍历哈夫曼树 return0; }
测试结果:
1a 2b 5c 7d 4e 13f 3g 6h 11i 8l