树集的数据结构。


10

尝试可以有效存储元素列表。前缀是共享的,因此节省了空间。

我正在寻找一种有效存储树的类似方法。我希望能够检查成员资格并添加元素,知道给定树是否为某些存储树的子树,或者是否存在存储树为给定树的子树也是可取的。

我通常会存储大约500棵高度小于50的不平衡二叉树。

编辑

我的应用程序是使用某种记忆的某种模型检查器。想象一下,我有一个状态和以下公式:和其中是一个复杂的子公式,并想象我首先想知道是否在成立。我检查成立,经过冗长的过程后,我确定是这种情况。现在,我想知道是否在成立。我想记住成立的事实,并注意到这样我几乎可以立即得出中。˚F = φ = φ ψ φ ˚F 小号φ 小号˚F ˚F 小号sf=ϕg=(ϕψ)ϕfsϕgsfgfgs
相反,如果我已经证明不能满足,那么我想告诉我们不能立即满足。˚F gtft

我们可以在公式上建立偏序,并具有 iff。对于每个状态,我们存储两组公式;存储保存的最大公式,存储不保存的最小公式。现在给定状态和公式,我可以看到,或者在这种情况下我是完成后,我直接知道是否在成立。˚F 小号大号小号小号小号˚F 大号小号˚F ˚F 小号˚F 小号gfgfsL(s)l(s)sgfL(s),fgfl(s),gfgs

目前,和被实现为列表,这显然不是最佳选择,因为我需要分别遍历所有存储的公式。如果我的公式是序列,并且如果偏序是“是...的前缀”,则特里证明可能更快。不幸的是,我的公式具有基于,模态运算符和原子命题的树状结构。¬ Ll¬,

正如@Raphael和@Jack指出的那样,我可以对树进行排序,但是我担心它不能解决问题,因为我感兴趣的部分顺序不会对应于“是的前缀”。


只是一个简单的想法:您是否尝试过对树进行序列化(执行有序遍历,相应地列出访问的节点,并添加用于上下移动的特殊元素)并将其存储在树中?当然,从某种意义上说,这将“仅”允许检查左子树。
拉斐尔

2
如果仅使用具有以下属性的树的序列化怎么办:当且仅当是的子串时,是的子树?构造这样的很简单[如果您首先找到树的规范形式]。此后,您的问题等同于子字符串匹配,这是字符串学中广泛研究的问题。Ť Ť '小号Ť 小号Ť '小号STTS(T)S(T)S
Jukka Suomela 2011年

1
看一下术语索引
starblue 2011年

1
另一个快速的想法是将所有树t1,t2,...存储在一个大树T中,为每个边缘记住它所属的树集。然后,要确定f是否是其中一个存储树的子树,您首先要确定f是否是T中的子树,如果是,则与该子树的所有边缘标签集相交。如果交集为非空,答案是肯定的。(您也可以将两个步骤结合在一起)。
Martin B.

Answers:


5

您可能要签出g-tries。本质上,这是您要查找的数据结构,但设计用于一般图形而不是仅用于树。因此,我不确定g-tries是否具有良好的理论保证-我认为它们使用图形规范化算法作为子例程-但实际上它们似乎运行良好。

(不要害怕链接的文章是关于“生物网络中的网络主题”的:g-trie是一个非常好的图形抽象数据结构。)


4

持久性是一种特殊的形式:请参见Driscoll,Sarnak,Sleator和Tarjan撰写的使数据结构持久化的论文,以及Sarnak&Tarjan的使用持久性搜索树进行平面点定位的文章,其中存储了相关树的族。


1
感谢您的参考。我目前无法访问“ 使数据结构持久化 ”,但是我对持久性的概念有些熟悉。但是,我看不到如何使用持久性来解决问题。我实际上想使用将字典映射到布尔值的字典,而同一棵树可能是不同字典中不同值的关键。
阿卜杜拉

1
由于我不确定您的应用程序是什么,因此我触发了类比尝试,即通过共享前缀存储字符串。但是,您的评论“同一棵树可能是不同字典中不同值的关键”,这似乎也不适合尝试。也许您只希望可以查找一棵树(及其所有子树)的签名集?(例如,对二叉树使用加泰罗尼亚编号,对带标签的树使用Prufer代码。)
杰克

1

这听起来有点像一片森林(不相交的森林)...

它通过称为“ 按等级集”的技术和使用路径压缩的搜索操作来摊销插入的成本。我知道Sylvain Conchon和Jean-ChristopheFilliâtre 也开发了这种结构的持久版本,但我不知道这是否与Jack提到的相同...



0

Chris Okasaki在“ Purely Functional Data Structures”(1998年)中提出了使用类型聚合(10.3.2)尝试二叉树的尝试。

我不知道这是否立即有所帮助;给出的解决方案可能无法直接实现。


0

在程序员的术语中:如果您从常见的子表达式/ trees / DAGs创建树,则将有一个很好的紧凑模型。有向无环图。然后一组树木就足够了。

公共类Tree {字符串操作;Tree []子树;

public int compareTo(Tree rhs) {
    if (rhs == null) return false;
    int cmp = operation.compareTo(rhs.operation);
    if (cmp == 0) {
        cmp = Arrays.compareTo(subtrees, rhs.subtrees);
    }
    return cmp;
}

...}

映射commonSubExpressions = new HashMap();

Tree get(String expressionSyntax){Tree t = new Tree(); t.operation = ...; t.subtrees = ...递归调用以获取子表达式;树t2 = commonSubExpressions.get(t); if(t2 == null){t2 = t; commonSubExpressions.put(t2,t2); } return t2; }}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.