次优查找树的原理是什么?

Posted 安然_随心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了次优查找树的原理是什么?相关的知识,希望对你有一定的参考价值。

原文地址:http://www.zhihu.com/question/21063814

为什么有:次优查找树?
(二叉)查找树:对有序数据进行查找,任何一种基于比较的查找策略都可以用一棵二叉树表示。每次查找过程就是从这棵二叉树的根节点出发,每次根据比较结果决定是走向左子树还是右子树还是停下来(因为已经找到了)。

查找树的效率:如果你又已知了每个元素可能被查找的概率,你就可以对一棵查找树计算它的期望比较次数。

最优查找树:在已知概率的情况下,期望比较次数最小的树。可以通过动态规划求出。

次优查找树:我不太喜欢这个译名。一般说“次优”意思是“第二优”,但是这里的“次优”的意思是“有时候就是最优,有时候是第二优,有时候我也不知道,总之,其实我什么都不知道”。

虽然什么都不知道,但是目标还是清楚的,就是希望在已知概率的情况下尽量减少构造出来的二叉查找树的期望比较次数。然后有时候动态规划太慢了,你就直接上贪心求一个还凑合的解就好了。

1、次优查找树是折半查找的一种一般形式,其理论基础是“被查找的各元素是不等概的”,而折半查找就是等概的,我们在使用中默认了这一性质。
比如,对于有序数组
int a = 1,2,3,4,5;
用折半查找时,应该现比较最中间的3,如果如果待查整数等于3,查找结束。如果小于3,就继续在左边的部分数组里查找;反之,在右边的数组里查找。
问题在于,我们为什么不从4开始找呢?为什么不从1开始呢?
因为在等概率的情况下,这样能让整体的平均搜索的长度(也就是次数)最小,实际也是二分查找树的深度最小。因为相同结点数的二叉树,越是丰满的二叉树高度越小。也就是说,每个节点的左右子树的高度差最小,二叉树的高度就越小,查找越底层的元素所需要的路径长度就越短,比较次数也越少(相同结点数完全二叉树的深度小于等于其他形态的二叉树的深度)。
我的ubuntu不好画图,给你个链接看看,你自己也可以画一下图。具有12个关键字的有序表,折半查找的平均查找长度()_牛客网。你把每个元素查找成功时的路径长度加起来看看,是不是完全二叉树最小?

2、现在我告诉你,每个元素被查找的概率是不一定相同的。刚才的办法还是最佳的吗?
比如按照刚才的查找树,元素5是最后一个,按照折半查找的话,每次查找都要花费3次比较才能找到,然而元素5被查找的概率是0.8,也就是说查了10000次,可能8000次都是它,那么这8000次查找就用了 times = 8000 * 3 = 24000次查找。但是如果把5放到查找树的根节点位置,那么是不是只需要8000次比较就行了?
所以,对于每个元素被查找的概率不同的情况下,折半查找不是最佳方法!

3、如果仅仅考虑查找成功的情况,构造一颗静态 最优查找树 的性能是最好的。
用数学公式来表示就是:使得的PH值最小的树为该数组的静态最优查找树。其中i为节点标号,为节点i的带权路径长度,,它等于结点i的查找路径长度c,乘以该结点被查找的概率p;h表示节点i在搜索树中的高度。
通俗点来说,就是权值越大的结点,越放到靠近根结点的位置!这个很好理解,这种结点要么查找概率大,要么需要的比较次数(折半查找中的次数)多,要么以上两者都占了,当然应该越早查越好啊,对不对?
然并卵,这种树的构造时间复杂度为,等你构造出来,天早就黑了好么……
关于为什么它的时间复杂度这么高,请参考http://www.cs.rutgers.edu/~kaplan/503/handouts/optimalbst.html或者Dynamic Programming

4、那么肿么办呢?我们来构造 次优查找树。
书上首先就告诉你了,这种树的查找效率很少低于最优查找树的3%。
核心:选出一个结点,使得它左右两侧的子数组的权值累加和之差的绝对值最小。把这个结点当做根节点,递归地用刚才的左右字数组构造它的左右子树。
数学表达式:。
之前的折半查找树是为了让左右子树的高度差尽量小,现在你就把高度的概念替换为权值之和来理解,就好了。为什么要让左右子树的权值累加和之差最小?为了使树的深度最小。

说了这么多,下面来上代码。请从主函数开始看,应该算是简单易懂

以上是关于次优查找树的原理是什么?的主要内容,如果未能解决你的问题,请参考以下文章

二叉查找树实现原理分析

20172330 2018-2019-1 《程序设计与数据结构》第七周学习总结

基于二叉排序树的查找

查找算法

HDOJ 5379 Mahjong tree

无标号树的计数原理(组合计数,背包问题,隔板法,树的重心)