数据结构哈弗曼树

#include <iostream>
using namespace std;
#define MAXVALUE 1000
#define N 100


typedef struct
{
int weight;
char data;
int parent;
int lchild;
int rchild;
}HNodeType;


typedef struct{
        int bit[N];           //用来保存字符的哈弗曼编码
        int start;           //表示该编码在数组中的起始位置
}HCodeType; 
                                                           //n为叶子节点的个数
void menu()
{
printf("请输入您要完成的功能所对应的序号:\n");
printf("1.构造哈弗满树\n");
printf("2.求哈夫曼编码\n");
printf("3.对给定数据加密\n");
printf("4.对密文进行解密\n");
printf("0.退出程序\n");
}


void Create_HaffmanTree(HNodeType HFMTree[],int n )         //构造哈夫曼树于HFMTree[ ],n为叶子节点的个数
{
int m1,x1,m2, x2, i,j;    
for (i=0;i<2*n-1;i++)          //数组HuffNode[ ]初始化
    {
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
    }
for (i=0;i<n;i++)
{    
cout<<"请输入第" << i+1 << "个叶子节点的值:";
cin>> HFMTree[i].data ;       //输入n个叶子节点的数据    
cout<<"请输入第" << i+1 << "个叶子节点的权重:";
cin>> HFMTree[i].weight ;                                   //输入n个叶子结点的权值
cout<<endl;  
}
for (i=0;i<n-1;i++)                                             //构造哈夫曼树
    { 
x1=x2=MAXVALUE;
m1=m2=0;
for (j=0;j<n+i;j++)                                         //选取最小和次小两个权值
{
if (HFMTree[j].parent==-1&& HFMTree[j].weight<x1)

x2=x1;
m2=m1;
x1= HFMTree[j].weight;
m1=j;
}
else   if (HFMTree[j].parent==-1 && HFMTree[j].weight<x2)

x2=HFMTree[j].weight;
m2=j;
}
}//以下是将找出的两棵子树合并为一棵子树
HFMTree [m1].parent=n+i;
HFMTree [m2].parent=n+i;
HFMTree [n+i].weight =HFMTree [m1].weight+HFMTree [m2].weight;
HFMTree [n+i].lchild=m1;
HFMTree [n+i].rchild=m2;


}       
}


void HaffmanCode(HNodeType HFMTree[], HCodeType HuffCode[ ],int n)
{
   HCodeType  cd;                                                    //字符编码的缓冲变量
   int i,j,c,p;
   for(i=0;i<n;i++)                                                  //求每个叶子结点的哈夫曼编码
   { 
   cd.start=n-1;
   c=i;
   p=HFMTree[c].parent;                                          //注意c和p的关系
   while (p!=-1)                                                 //由叶子结点向上直到树根
   { 
   if (HFMTree[p].lchild==c)
   cd.bit[cd.start]=0;
   else
   cd.bit[cd.start]=1;
   cd.start--;
   c=p;
   p=HFMTree[c].parent;
   }
   for (j=cd.start+1;j<n;j++)                                       //保存求出的每个叶结点的哈夫曼编码和编码的起始



   HuffCode[i].bit[j]=cd.bit[j];
   HuffCode[i].start=cd.start+1;
   }                                                                    //求每个叶子结点的哈夫曼编码
   
   for (i=0;i<n;i++)                                                    //输出每个叶子结点的哈夫曼编码
   { 
   cout<<HFMTree[i].data <<endl;
   for (j=HuffCode[i].start;j<n;j++)
   cout<<HuffCode[i].bit[j];
   cout << endl;
   }
}


void main()

HNodeType bt[MAXVALUE];
    HCodeType bt1[MAXVALUE];
int n,note;
while(1)
{
menu();
cin>>note;
switch(note)
{
case 1: 
    cout<<"请输入叶子节点的数量:"<<endl;
cin>>n;
cout<<endl;
Create_HaffmanTree(bt,n);
break;
case 2: HaffmanCode(bt,bt1,n);
    break;
case 3: break;
case 4: break;
case 0: exit(0);
}
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
上机实验2 栈和队列及其应用 停车场的管理 [问题描述] 设停车场是一个可停放n辆汽车的狭长通道,且只有一个门可供出入。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆汽车即可开入;当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原顺序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。 [基本要求] 以栈来模拟停车场,以队列来模拟车场外的便道。按照从中端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息,汽车的牌照号以及汽车到达或离去的时刻。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(便道上停留的时间不收费)。栈以顺序结构实现,队列以链表结构实现。 [测试数据] (1) 设n=2,输入数据为:('A',1,5),('A',2,10),('D',1,15),('A',3,20),('A',4,25),('A',5,30),('D',2,35),('D',4,40),('E',0,0).’A'表示Arrival,'D'表示Departure;'E'表示输入结束End. (2) 自定义测试数据 [提示] 需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也可用顺序存储结构实现。输入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含两个数据项:汽车的牌照浩和进入停车场的时刻。 [选做] (1) 汽车可有不同种类,根据占地面积收费标准不同。如1辆客车和2辆小汽车的占地面积相当,1辆大型货车的面积相当于3辆小汽车的占地面积,如何修改数据结构,满足上述收费标准。 (2) 若汽车可直接从便道开走,则排在它前面的汽车要先让道,然后按原顺序恢复排队队列,如何实现?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值