【SSLGZ 1407】(树)哈夫曼树(一)

本文介绍了如何构建哈夫曼树,并给出了样例输入和输出。通过将数据从小到大排序,每次合并最小的两棵子树,重复此过程直到形成单一哈夫曼树。中序遍历该树,可以得到节点的二进制表示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述
给出数据,构建哈夫曼树。(按中序遍历输出)
样例输入
8
7
19
2
6
32
3
21
10
样例输出
19:00
21:01
2:10000
3:10001
6:1001
7:1010
10:1011
32:11
算法讨论
将构建哈夫曼树的模板敲上去就能对了。如何构建哈夫曼树?先将数据从小到大排序,将每个数据当做一棵子树,将最小的两个合并成一棵子树,再次排序,如此重复直到只剩一颗树。最终得到的就是一棵哈夫曼树。

const
  maxn=100;
var
  a:array[0..maxn,1..2] of longint;
  f:array[0..maxn,1..3] of longint;
  v:array[0..maxn] of longint;
  i,j,n,t:longint;
  flag:boolean;

procedure sort(k:longint);
var
  i,j,t:longint;
begin
  for i:=1 to k-1 do
    for j:=i+1 to k do
      if a[i,1]>a[j,1]
        then begin
               t:=a[i,1]; a[i,1]:=a[j,1]; a[j,1]:=t;
               t:=a[i,2]; a[i,2]:=a[j,2]; a[j,2]:=t
             end;
end;

procedure vist(t:longint);
var
  j:longint;
begin
  if f[t,1]=0
    then begin
           flag:=true;
           exit
         end;
  v[i]:=0;
  inc(i);
  vist(f[t,2]);
  dec(i);
  v[i]:=1;
  inc(i);
  vist(f[t,3]);
  dec(i);
  v[i]:=-1;
  if flag
    then begin
           write(f[t,1],':');
           for j:=1 to i-1 do
             write(v[j]);
           writeln; 
           flag:=false
         end;
end;

begin
  read(n);
  for i:=1 to n do
    begin
      read(a[i,1]);
      f[i,1]:=a[i,1];
      a[i,2]:=i
    end;
  t:=n+1;
  i:=n;
  while i>1 do
    begin
      sort(i);
      f[t,1]:=a[1,1]+a[2,1];
      f[t,2]:=a[1,2];
      f[t,3]:=a[2,2];
      a[1,1]:=f[t,1];
      a[1,2]:=t;
      a[2,1]:=a[i,1];
      a[2,2]:=a[i,2];
      inc(t); dec(i)
    end;
  fillchar(v,sizeof(v),255);
  i:=1;
  vist(t-1)
end.

这里写图片描述
Pixiv ID:60481857

数据结构关于二叉的建立遍历以及应用二叉进行编解码 实验要求 必做部分 1. 小明会按照前序的方式输入棵二叉。例如,输入$ACG##H##D##BE#I##F##的话,代表了下面这棵: 2. 请分别按照前序、中序、后序输出这棵。 选做部分 背景 在影视剧中,我们经常会看到二战期间情报人员使用电报哒哒哒地发送信息,发送电报所使用的编码叫做摩尔斯电码(或者叫做摩斯密码)。甚至在现代,SOS仍然是国际通用的求救信号之,其“三短、三长、三短”同样是摩斯密码的编码方式。 摩斯密码使用若干个“点”和“划”来表示个字母,字母和字母之间使用短暂的停顿来表示。例如,种常见的编码方式为: 字母 摩斯密码 字母 摩斯密码 A .- E . B -... F ..-. C -.-. G --. D -.. H .... 实际上,个摩斯密码本可以使用棵二叉来存储: 上图表示,从根节点start开始,遇到个点(Dot)就访问它的左子节点,遇到个划(Dash)就访问它的右子节点。例如,三个点...代表了S,三个划---代表了O。所以SOS的摩斯密码是... --- ...(中间用空格隔开,表示短暂的停顿)。再比如,爱疯手机有种来电铃声的节奏为“哇哇哇 哇-哇- 哇哇哇”,这其实表示的是…… 现在,小明想在课上偷偷跟你传纸条,但又不想被其他同学看到内容。因此他跟你约定,每次给你传纸条时都使用摩斯密码来编写。至于密码本,当然不能使用国际通用的,他会在课前告诉你密码本的内容。然而小明发现,每次写纸条、读纸条都不是很方便,所以他想让你做个程序来自动编码/解码你们的摩斯密码。 题目要求 首先,小明输入的那棵二叉,代表了你们在这堂课上要使用的摩斯密码本。例如,输入$ACG##H##D##BE#I##F##的话,代表了下面这棵: 第个字母$是什么并不重要,因为它只是代表了根节点,而根节点在我们的摩斯电码中并不代表个字符,仅仅代表“start”。 读入密码本后,请记得按照前序、中序、后序输出这棵。 然后,小明会输入个数,代表接下来输入的是明文还是摩斯电码。输入0表示接下来他会输入明文,输入1表示接下来输入的是摩斯电码,输入-1程序退出。 1. 如果输入的是0,代表接下来要输入的是明文。程序接受个字符串,根据字符串中每个字母输出对应的摩斯电码,用空格隔开。例如如果小明输入“BED”,则程序应该输出“-空格-.空格.-”。如果遇到密码本中没有的字符,则输出“输入有误”。 2. 如果输入的是1,则表示接下来要输入摩斯电码。小明首先会输入个数字N,代表有几个电码的输入,例如输入4代表之后会输入4个电码(即这个单词有四个字母)。随后输入空格分割的电码,例如, .. . -- -. 程序需要根据摩斯电码解读出明文单词并输出,例如上面的电码表示“CAFE”。如果遇到密码本中没有的编码,则输出“输入有误”。 输入输出样例 必做部分: 请输入二叉: $ACG##H##D##BE#I##F## 前序遍历:$ACGHDBEIF 中序遍历:GCHAD$EIBF 后序遍历:GHCDAIEFB$ 选做部分: 请选择(0为明文,1为电码,-1退出):0 请输入明文:BED 摩斯电码为:- -. .- 请选择(0为明文,1为电码,-1退出):1 请输入电码个数:4 请输入电码:.. . -- -. 明文为:CAFE 请选择(0为明文,1为电码,-1退出):-1 // 程序结束
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值