【问题标题】:Binary Tree's usage二叉树的使用
【发布时间】:2010-12-14 11:44:44
【问题描述】:

谁能给我一个需要使用二叉树甚至只是普通树的真实示例(在编程中,C#)?

我了解二叉树的原理以及它们的工作原理,但我正在尝试找到一些实际使用的示例?

托尼

【问题讨论】:

标签: binary-tree


【解决方案1】:

一个简单的例子是搜索。例如,如果您将列表数据存储在树中,您将获得 O(log(n)) 查找时间。列表的标准数组实现将实现 O(n) 查找时间。

【讨论】:

  • 所以你也可以将任何你想存储在数组中的东西存储在树中吗?但是在树中查找时间更短......我想这只会在包含大量数据的数据结构中发挥作用。
  • @Tony:不一定。任何具有显式层次结构的东西都非常适合树(可能不是二叉树,但一般来说肯定是树),即使它不是那么多项目。 (想想你的家谱:即使你不知道你的许多亲戚,它仍然是一棵树!)
  • 二叉搜索树需要 *O**(log2 *n) 比较。线性列表需要 **O**(*n*/2)。在 8 个元素处,您会发现树需要(最多)3 次比较,但线性搜索需要(平均)4 次。
  • 线性列表需要 n 次比较,尽管给定一个完全随机的列表分布,但您会在 n/2 次比较中找到您的元素。请不要滥用大 O 符号。此外,日志的基础取决于每个级别的节点,这就是我省略两者的原因。没有人提到二叉树。
  • 明确一点,O(n/2) = O(n),O(log_2(n)) = O(log_k(n))
【解决方案2】:

在 Java 中,树用于实现某些排序的数据结构,例如 TreeSet:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeSet.html

它们用于您希望顺序基于元素的某些属性而不是插入顺序的数据结构。

【讨论】:

    【解决方案3】:

    XML、HTML(和 SGML)文档是树。

    【讨论】:

    • 但它们不是二叉树吗?因为它们可能有两个以上的子节点属于一个节点,所以不符合二叉树规则。
    • 它们是 n 叉树,任何节点都可以有任意数量的子节点。它用于灵活性(因此您的 HTML 文档可以具有任何结构),其中构建二叉树及其表亲(红色/黑色等)以存储大量数据并相对于数字非常快速地插入或检索任何数据项存储在树中的东西。
    • 嗯-现在我不记得 n-ary 树是否是正确的术语。不过,我的其余描述还可以。
    • n-ary tree 听起来很合理,如果有更广泛使用的术语我暂时想不到。
    • 您可以从二叉树节点构建 n 叉树。您的二叉树具有“兄弟”和“子”链接。兄弟链接创建一种链表。
    【解决方案4】:

    Balanced binary trees,存储按排序维护的数据,用于实现 O(log(n)) 的查找、删除和插入时间。 “平衡”只是意味着在最浅和最深叶子的深度之间存在有界限制,将空的左/右节点计为叶子。 (最好左右子树的深度最多相差一个,一些实现放宽了这个以使算法更简单)

    您可以使用数组而不是树,通过二进制搜索按排序顺序来实现 O(log(n)) 查找时间,但插入/删除时间为 O(n)。

    一些树(特别是数据库的 B-trees)每个节点使用超过 2 个分支,以扩大树并减小最大深度(这决定了搜索时间)。

    我想不出使用未按排序顺序维护的二叉树的理由(这里的大多数答案都没有提到这一点),但也许有一些应用程序。 除了排序的二叉平衡树之外,任何具有层次结构的东西(正如其他回答者提到的,XML 或目录结构)都是树的一个很好的应用程序,无论是否是二叉树。

    编辑: re:未排序的二叉树:我只记得 LISP 和 Scheme 都大量使用不平衡二叉树。 cons 函数接受两个参数(例如 (define c (cons a b)) )并返回一个树节点,其分支是两个参数。 car 函数接受这样一个树节点并返回给cons 的第一个参数。 cdr 函数类似,但将第二个参数返回给 cons。最后nil 代表一个空对象。这些是用于在 LISP 和 Scheme 中制作所有数据结构的原语。列表是使用极端不平衡的二叉树实现的。包含文字元素 'Alabama'Alaska'Arizona'Arkansas 的列表可以显式构造为

    (cons 'Alabama (cons 'Alaska (cons 'Arizona (cons 'Arkansas nil))))
    

    并且可以使用carcdr进行遍历(其中car用于获取列表头部,cdr用于获取不包括列表头部的子列表)。这就是 Scheme 的工作原理,我认为 LISP 是相同或非常相似的。更复杂的数据结构,如二叉树(每个节点需要 3 个成员:两个保存左右节点,第三个保存节点值)或每个节点包含两个以上分支的树,可以使用列表来构建实现每个节点。

    【讨论】:

      【解决方案5】:

      Unix 中的目录结构如何。例如,du 命令,即磁盘使用命令对表示目录结构的树进行后序遍历(遍历顺序::左子节点-> 右子节点-> 根节点),以获取该目录使用的磁盘空间。

      以下幻灯片应该会有所帮助。

      http://www.cse.unt.edu/~rada/CSCE3110/Lectures/Trees.ppt

      干杯

      【讨论】:

      • 很好的例子——虽然目录结构不是二叉树
      • 是的,它们不是二叉树。我刚刚发布了这个,因为托尼在他的问题中提到了普通的树。
      【解决方案6】:

      在 C#、Java、Python、C++(使用 STL)和其他高级语言中,大多数时候您将使用其中一种内置/包含库的类型来存储数据,至少是数据您目前正在工作,因此大多数时候您不会明确使用二叉树或其他类型的树。

      话虽如此,其中一些内置类型在“后台”实现为一种或另一种树,在某些情况下,您必须自己实现一个。

      另外,你必须知道的相关事情是二分搜索。这主要是在二叉树(二叉搜索树:P)中完成的,但这个想法可以外推到很多问题,即使不涉及树,所以试着好好理解它。

      编辑:现实生活中的经典例子:

      假设您想在大城市的电话指南中搜索特定人的电话号码。在所有条件相同的情况下,您将大致在中间打开它,在该页面中寻找那些人,并查看您的“目标”是在它之前还是之后,从而将数据减少了一半。然后你在你知道你的“目标”的那一半重复这个操作,一次又一次,直到你找到你的“目标”。每次您查看之前一半的数据时,您总共需要 log(base 2) n 次操作才能达到您的“目标”,其中 n 是数据的总大小。

      因此,在 100 万个电话簿中,您会在 log(base 2) 100 万 = 20 次比较中找到您的目标,而不是像线性搜索那样逐个比较(在最坏的情况下是 100 万次比较)。

      请注意,这仅适用于已排序的数据。

      【讨论】:

        【解决方案7】:

        这里有一些例子:

        • 已解析程序或表达式的内存表示是一棵树。对于表达式(不包括三元运算符),树将是二元的。

        • GUI 的组件以树的形式组织。

        • 任何“包含”层次结构都可以表示为树。 (HTML、XML 和 SGML 就是示例。

        当然,二叉(和 n 元)树可以用来表示索引、映射、集合和其他“通用”数据结构。

        【讨论】:

          猜你喜欢
          • 2015-06-10
          • 1970-01-01
          • 1970-01-01
          • 2012-01-09
          • 1970-01-01
          • 2017-04-14
          • 2012-04-04
          • 2011-09-16
          • 2023-03-08
          相关资源
          最近更新 更多