9

我想在 Scala 中实现一棵树。我的特定树使用 Swing Split 窗格来提供地理地图的多个视图。拆分窗格中的任何窗格本身都可以进一步划分以提供额外的视图。我是否正确地说 TreeMap 和 TreeSet 都没有提供 Tree 功能?如果我误解了这一点,请原谅我。令我震惊的是,应该有标准的 Tree 集合,并且不断重新发明轮子是不好的做法。是否有任何可能成为未来 Scala 标准的 Tree 实现?

所有的树都具有三种类型的元素:根、节点和叶子。叶子和节点必须有一个对父节点的引用。Root 和 Nodes 可以对子节点和叶子有多个引用。叶子有零个孩子。如果不删除它们的子节点,就不能删除节点和根。我可能错过了其他规则/约束。

这似乎足以证明标准集合的合理性。我还建议在 Root 和 Nodes 只能有 2 个孩子或一个叶子孩子的情况下,应该有一个标准的子类集合。这就是我在特定情况下想要的。

4

5 回答 5

26

实际上,一棵树本身既无用又很难指定。

从后者开始,严格来说数据结构,一棵树可以有多少个孩子?节点是否存储值?节点是否存储元数据?孩子对父母有指点吗?您将树存储为带有指针的节点,还是作为数组上的位置元素?

这些都是答案是“取决于”的问题。事实上,你说孩子有指向他们父母的指针,但对于任何不可变的树来说都不是这样!当某些树实际上存储为单个数组(例如Heap)上的节点时,您似乎还假设树始终存储为具有引用的节点对象。

此外,并非所有这些要求都能得到满足——有些是相互排斥的。即使你忽略了这些,你仍然会留下一个数据结构,它没有针对任何东西进行优化并且使用起来很笨拙,因为你必须处理许多与你无关的细节。

然后,还有第二个问题,那就是一棵树本身是没有用的。TreeSetTreeMap利用特定的树,其插入/删除/查找算法使它们成为排序数据的良好数据结构。然而,这根本不是树的唯一用途。树可用于搜索空间算法、表示类似树的真实世界信息、组成文件系统等。有时任务是在图中找到一棵树。这些用途中的每一种都需要不同的表示形式和不同的算法——这些算法使它们变得有用。

而且,最重要的是,编写一个树类是微不足道的。问题是编写算法来操纵它。

于 2012-08-19T02:56:06.430 回答
5

将“树”作为GUI 小部件(您似乎指的是它)的概念与作为有序数据结构的树之间存在一些不匹配。在前一种情况下,它只是一个嵌套序列,在后一种情况下,目的是提供例如快速搜索算法,并且您不会随意操纵内部结构,其中通常分支因子是恒定的并且树高保持平衡等。后者的一个例子是collection.immutable.TreeMap使用称为红黑树的自平衡二叉树结构。

所以这些数据结构对于桥接到javax.swing.TreeModel. 关于这个接口几乎没有什么可以做的,所以你可能会坚持使用默认实现DefaultTreeModel,一个可变的非泛型结构(这是单线程 Swing 所需要的全部)。

有关使用 scala-swingJTree包装器的讨论,请参阅此问题。它还有一个指向 Scala 库的链接JTree

于 2012-08-18T12:43:36.170 回答
3

由于您可以在 Scala 中使用 java 类,因此请查看javax.swing.tree包:http ://docs.oracle.com/javase/6/docs/api/javax/swing/tree/package-summary.html ,尤其是TreeModelandTreeNode和. 它们被设计为与 Swing 一起使用,但几乎是标准的树实现。MutableTreeNodeDefaultMutableTreeNode

除此之外,实现(通用)树应该非常简单。

于 2012-08-18T11:11:34.847 回答
2

由于 gui 应用程序对树集合的性能要求较低,您可以使用受限于仅表示树结构图的通用图形库: http: //scala-graph.org/

于 2014-03-29T00:34:58.173 回答
1

TreeSet并且TreeMap都基于RedBlack

红黑树是平衡二叉树的一种形式,其中一些节点被指定为“红色”,其他节点被指定为“黑色”。像任何平衡二叉树一样,对它们的操作在与树大小成对数的时间上可靠地完成。

(引自Scala 2.8 Collections

RedBlack没有很好地记录,但是如果您查看它的来源TreeSet并且TreeMap很容易弄清楚如何使用它,尽管它不能满足您的所有(大多数?)要求(节点没有对父级的引用, ETC)。

于 2012-08-18T12:55:20.857 回答