数据结构_静态链表_哈夫曼

来源:互联网 发布:台湾人眼中的大陆知乎 编辑:程序博客网 时间:2024/05/21 03:55

1、建立一棵二叉链表树,分别输出此先根,中根,后根遍历序列(例如:输入:ABDH##I##E##CF#J##G##)
2、将练习题编程,实现哈夫曼树的构建和哈夫曼编码设计(例如:输入n=5,权值=0.12 0.40 0.15 0.08 0.25)

#include<iostream>

#include<string>
#define UINT_MAX 10000
using namespace std;
struct node{
char a;
node *lchild;
node *rchild;
};
typedef struct node *btree;// 二叉链表树结构类型定义


struct HTNode{
    double  weight;
    int parent,lchild,rchild;
};
typedef struct HTNode *HuffmanTree; // 赫夫曼树结构类型定义


void createbt(btree &p)//建立二叉链表树
{
char a;
cin>>a;
if(a=='#'){
p=NULL;
}
else{
if(!(p=new node))
exit(1);
p->a=a;
createbt(p->lchild);
createbt(p->rchild);
}
}


void preorder(btree p)//先根遍历二叉链表树
{
if(p!=NULL)
{
cout<<p->a<<'\t';
preorder(p->lchild);
preorder(p->rchild);

}
}


void inorder(btree p)//中根遍历二叉链表树
{
if(p!=NULL)
{
inorder(p->lchild);
cout<<p->a<<'\t';
inorder(p->rchild);
}
}


void postorder(btree p)//后根遍历二叉链表树
{

if(p!=NULL)
{
postorder(p->lchild);
postorder(p->rchild);
cout<<p->a<<'\t';
}
}
//*********************************************************************************
int min(HuffmanTree t,int i)  // 取小值函数

    int j,flag;
    double k=UINT_MAX; // 取k为不小于可能的值
    for(j=1;j<=i;j++)
{  
if(t[j].weight<k&&t[j].parent==0)
k=t[j].weight,flag=j;
}
    t[flag].parent=-1;
    return flag;
}


void select(HuffmanTree t,int i,int &s1,int &s2)  //取出最小权值的节点
{   // s1为最小的两个值中序号小的那个
s1=min(t,i);
s2=min(t,i);
}


void HuffmanCreate(HuffmanTree &HT,double *w,int n)
{
    int m,i,s1,s2;
HuffmanTree p;
if(n<=1)  
return;
m=2*n-1;
HT=new HTNode[m+1]; 
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).parent=0;
for(i=n+1;i<=m;++i) // 建立夫曼树
{      
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}


void HuffmanCode(HuffmanTree &HT,char HC[][100],double *w,int n)
{
int m,i,s1,s2,start;
    int c,f;
char *cd;
    cd=new char[n]; // 分配求编码的工作空间
cd[n-1]='\0'; // 编码结束符
for(i=1;i<=n;i++) // 逐个字符求赫夫曼编码
{   
start=n-1; // 编码结束符位置
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'; 
strcpy(HC[i],&cd[start]); // 从cd复制编码(串)到HC
}
delete cd;
}


void main()
{
int num;
cout<<"请选择:"<<endl;
cout<<"1、二叉链表树"<<endl;
    cout<<"2、哈夫曼树"<<endl;
    cin>>num;
if(num==1)
{
cout<<"二叉链表树:"<<endl;
cout<<"输入数据:"<<endl;
btree p; 
createbt(p);
cout<<"先根遍历:"<<endl;
preorder(p);
cout<<"\n";
cout<<"中根遍历:"<<endl;
inorder(p);
cout<<"\n";
cout<<"后根遍历:"<<endl;
postorder(p);
cout<<"\n";
}
else if(num==2)
{
cout<<"哈夫曼树:"<<endl;
HuffmanTree HT;
int n,i;
double *w;
cout<<"请输入权值的个数:"<<endl;
cin>>n;
w=new double[n];
char HC[100][100];
cout<<"请依次输入"<<n<<"个权值:"<<endl;
for(i=0;i<=n-1;i++)
cin>>w[i];
HuffmanCreate(HT,w,n);
HuffmanCode(HT,HC,w,n);
for(i=1;i<=n;i++)
cout<<"第"<<i<<"数的哈夫曼编码为:"<<HC[i]<<endl;
}
else 
{
cout<<"error!!!请输入正确的选择!!!"<<endl;
        exit(1);
}

}


上面的实现是在静态链表实现的,另一种方法是http://wenku.baidu.com/link?url=RX84yH5NGedCRlw4sBkparocADwbhyy4ddQzp-zPxYwKQ_hJvnTK8cSH1X-OhNMgVh0s_qAw_dy0KPep4YvoNh4u4cXtuZA85X9HqiR7ViC

用最小堆可以在日后实现。



0 0
原创粉丝点击