程序优化杂谈——最优二叉树在程序中的应用

原创 2004年09月10日 17:06:00
关键字:程序,优化,哈夫曼,最优二叉树
  首先呢,我想和大家讨论一个非常简单的问题:分类。
  假设这里有100个物品。其中属于A类的物品有20个;B类10个;C类45个;D类15个;E类10个。现在要求写一个程序对这100个物品进行分类。啊!这个问题是不是很简单呢?你闭着眼睛也应该能写出来。这里我用伪C语言来写这个程序。先约定:x[0]~x[99]是这100个物品。“in”操作判断物品是否属于该类。“put”操作是将物品放入这个分类的中。
程序:
10 for(i=0;i<100;i++)
20 {
30 if(x[i] in a)
40 x[i] put a;
50 else
60 if(x[i] in b)
70 x[i] put b;
80 else
90 if(x[i] in c)
100 x[i] put c;
110 else
120 if(x[i] in d)
130 x[i] put d;
140 else
150 x[i] put e;
160 }
  “啊哈!多么漂亮的程序啊。”
  的确,这段代码从某个方面来说是非常不错的。很工整。但是这是最好的么?让我们计算一下看看。
不论如何优化“x[i] put x;”这句肯定要执行100次,因为一个物品必须放入一个分类。且只能放一次。那么能变化的就是比较的次数。先看下面这个图,是上面这段程序的一个树型结构图:

  我们很容易能计算出来这个结构在进行比较的时候,需要进行275次比较。那么怎么样才能减少比较的次数呢?
  实际上这是一个权值的问题。属于A类的物品有20个;B类10个;C类45个;D类15个;E类10个。那么我们不防设A的权值为0.2,B的权值为0.1,C的权值为0.45 ,D的权值为0.15,E的权值为0.1。那么根据最优二叉树的概念,应该把权值大的深度减到最小(详细的情况请参看清华大学出版的《数据结构》,关于哈夫曼编码那部分)。根据这个原则,我们应该将B、E向下调整,而C向上调整。于是又了下面这个新的结构:

  按照这个结构从新写这个程序,再运行试试?比较次数被减少到了210次。很有意思不是么?
10 for(i=0;i<100;i++)
20 {
30 if(x[i] in c)
40 x[i] put c;
50 else
60 if(x[i] in a)
70 x[i] put a;
80 else
90 if(x[i] in d)
100 x[i] put d;
110 else
120 if(x[i] in b)
130 x[i] put b;
140 else
150 x[i] put e;
160 }
  为什么会这样呢?前面我只说了怎么做,没说为什么这么做。下面我和大家一起做个简单的分析。
  首先看这两段程序有什么不同的地方。
  第一段程序和第二段程序唯一不同之处就是判断的顺序不同。第一段程序判断的顺序是A、B、C、D、E。而第二段程序的判断顺序是C、A、D、B、E。奇怪的顺序不是么?其实一点都不奇怪,如果你按第二种顺序排列的时候写上权值你就发现其中的奥妙了:
C | A | D | B | E
0.45 | 0.2 | 0.15 | 0.1 | 0.1
是的,它的权值是从大到小排列的。
  为了说明得更透彻些,下面再来分析一下程序运行的过程。
  行30那段程序不论怎么调整,总是要运行100次的。而后面的程序是否执行则受前面的程序条件判断的结果影响。如果判断为真,则不执行后面的程序。如果将权值大的比较放的深度深,那么无形之中就将整棵比较树的权值加大了。反过来,整棵树的权值就小。而这种优化的思想就是在这——尽量降低整体的权值。
  学过数据结构的朋友一定会说:“你这个优化并不是最优二叉树。”是的,最优二叉树的结构应该是这样的:

  但是程序优化有它的特殊性。如果你完全按照最优二叉树来优化,会发现判断条件非常复杂,并且判断次数没有减少(在本例中是这样,别的情况但并不一定。)。实际上是增加了程序的运行时间。
  我给大家给了一个C#做的例子。大家可以比较一下之间的差异。可以到我的站上去下载 www.xxiyy.com

算法基础(八):超详细最优二叉树构建(1)

算法基础(八):超详细最优二叉树构建(1)
  • huiguimoyu
  • huiguimoyu
  • 2014年04月27日 18:55
  • 1754

最优二叉树--哈夫曼树和最优前缀编码--哈夫曼编码

1.最优二叉树的定义最优二叉树又称哈夫曼树,是一种带权路径长最短的树。树的路径长度是从树根到每一个叶子之间的路径长度之和。节点的带树路径长度为从该节点到树根之间的路径长度与该节点权(比如字符在某串中的...
  • skyroben
  • skyroben
  • 2017年05月18日 11:56
  • 2420

动态规划4-最优二叉查找树

前面说过动态规划最典型的就是解决最优化问题的(具有最优子结构的最优化问题),最优二叉查找树就是一个典型的最优化问题。 问题描述: 给定一个n元素的中序序列,它可以有卡特兰数个不同形状的二叉排序树...
  • mengzhejin
  • mengzhejin
  • 2014年07月16日 16:25
  • 1954

ACM程序设计选修课——Problem D: (ds:树)合并果子(最优二叉树赫夫曼算法)

Problem D: (ds:树)合并果子 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 80  Solved: 4 [Submit][Status][...
  • a88770202
  • a88770202
  • 2016年04月09日 14:39
  • 263

完成基于哈夫曼树(最优二叉树)的压缩及解压小程序的收获

收获      1) 更有条理的构造我的代码了: 先从main方法下手,将自己想要的实现程序的功能以注释 的方式写出来,然后再逐渐细化每一部分的功能,每部分的功能都有非常明确的输入部分,将这些...
  • Mc_Id
  • Mc_Id
  • 2015年07月16日 22:32
  • 486

最优二叉树应用-编码与译码

  • 2015年10月02日 09:40
  • 296KB
  • 下载

数据结构实验报告《五、最优二叉树应用之哈夫曼编译码》

  • 2011年11月29日 20:46
  • 293KB
  • 下载

哈夫曼树及其应用-最优二叉树

最优二叉树概念 1.树的路径长度   树的路径长度是从树根到树中每一结点的路径长度之和。在结点数目相同的二叉树中,完全二叉树的路径长度最短。 2.树的带权路径长度(Weighted Path L...
  • qilixiang012
  • qilixiang012
  • 2014年08月20日 20:59
  • 519

霍夫曼树及其应用(最优二叉树)

哈夫曼数及哈夫曼编码   哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路...
  • zwz2011303359
  • zwz2011303359
  • 2017年03月16日 21:02
  • 185

最优二叉树——哈夫曼树

一:什么是最优二叉树? 从我个人理解来说,最优二叉树就是从已给出的目标带权结点(单独的结点) 经过一种方式的组合形成一棵树.使树的权值最小. 最优二叉树是带权路径长度最短的二叉树。根据结点的个数,权...
  • csh624366188
  • csh624366188
  • 2012年04月28日 18:05
  • 27418
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:程序优化杂谈——最优二叉树在程序中的应用
举报原因:
原因补充:

(最多只允许输入30个字)