【问题标题】:implementing binary trees - data structure, trie实现二叉树 - 数据结构,trie
【发布时间】:2013-09-15 19:22:25
【问题描述】:

二叉树。原理是可以理解的,但是从数组或关联数组的角度来看,它们到底是什么样子的呢?

如果我可以使用的数据结构是:

AssociativeArray={tag:value,tag:value,tag:value} 

(of course, each tag is unique)

Array=[value,value,value] 
(where the value can be any data type including array)

例子:

DictOfWords={greeting:"hello",sound:"music",sleep:"dream",words:["hello","music","dream"]}
listOfWords=["hello","music","dream",DictOfWords]

由其中一个或两个构建的二叉树会是什么样子?

此外,根据这些数据结构构建的单词搜索 trie 的数据结构是什么样的?

trie 的节点会是什么样子?它是关联阵列还是线性阵列或两者的某种组合?我理解from this post“一个树每个字符拥有一个节点”

顶层结构也应该是这样的:

trie={a:{},b:{},c:{}...}

trie={a:[],b:[],c:{}...}

trie=["a","b","c"...]

【问题讨论】:

  • 你能去维基百科看看en.wikipedia.org/wiki/Binary_treeen.wikipedia.org/wiki/Trie。如果这些不能回答你的问题,请回来在这里发表评论,我会帮助你理解它们。
  • 这正是我在回到 S/O 并发布此问题之前所做的!
  • 我想是什么让我感到困惑,那么,为什么你想用关联数组或数组来表达它们。关联数组和数组不是考虑二叉树的常用方法。事实上,我只听说过它在一种情况下使用这种方式(这是一种花哨的优化)。同时,Trie 页面提供了几个用各种语言有效地从关联数组构建的示例。 Dukeling 的回答说明了这个问题:您可以发明任何您喜欢的表示,但用于理解的有用表示不涉及数组或关联数组。
  • 尝试用不同的方式表达这种说法:有很多方法可以将二叉树的内容表示为数组或关联数组。但是,在二叉树上完成的所有操作都没有真正使用数组函数,并且如果您选择将平衡二叉树视为数组,则在平衡二叉树上完成的一些操作是无法实现的。
  • 我只需要处理这两种类型的数组。我不知道可以使用其他什么内置数据类型——字符串、整数、长整数、浮点数、双精度、数组、关联数组,仅此而已。看不到任何人如何在不使用数组和某种数组索引的情况下遍历任何内容的列表

标签: binary-tree trie


【解决方案1】:

Tries 和二叉树通常不被视为数组或关联数组。它们被认为是节点的集合,通常作为结构实现。例如,二叉树往往看起来像

struct BTreeNode
{
    value_type value;
    BTreeNode* left;
    BTreeNode* right;
};

Tries 看起来像

struct TrieNode
{
    char_type  letter;
    associative_array<char_type, TrieNode*> children;
};

现在,如果您只想使用数组和关联数组对此进行建模,那么问题将是:您打算用它们做什么?如果您需要做的只是将数据存储在树/特里结构中,那么您有很多选择。但是,如果您真的想将 BTree 用作 BTree 或将 Trie 用作 Trie,我们必须确保用于将结构转换为数组/关联数组的任何转换都有效。最简单的一种:将每个结构视为具有恒定条目数的关联数组

    4
   / \
  2   5
 / \   \
1   3   6

通常会这样做

BTreeNode oneNode(1, null, null);
BTreeNode threeNode(3, null, null);
BTreeNode twoNode(2, oneNode, threeNode);
BTreeNode sixNode(6, null, null);
BTreeNode fiveNode(5, null, sixNode);
BTreeNode fourNode(4, twoNode, fiveNode);

您可以将这些结构一对一转换为关联数组并获取

fourNode = {   value: 4,
               left: {
                   value: 2,
                   left: {
                       value: 1
                   },
                   right: {
                       value: 3
                   }
               },
               right: {
                   value: 5,
                   right: {
                       value:6
                   }
              }
          }

与数组有类似的转换,但读起来不太明显

存储“abc”“abd”“abe”“ace”的可比较trie创建一个看起来像这样的trie结构

    a
   / \
  b    c
/ | \   \

c d e

从结构到值的转换和上面一样,你得到

trie =  {
            letter: 'a',
            children: {
                'b': {
                    letter: 'b'
                    children: {
                        'c': { letter: 'c' },
                        'd': { letter: 'd' },
                        'e': { letter: 'e' }
                    }
                'c': {
                    letter: 'c'
                    children: {
                        'e': { letter: 'e' }
                    }
            }
       }

但是,站在我原来的 cmets 的立场上,“就数组或关联数组而言,它们真正看起来像什么?”是无法回答的。它们实际上根本没有实现为数组或关联数组,因此“看起来真的”不能与“数组或关联数组”一起使用。根据它们真正构建的节点结构来考虑它们,你会走得更远。

例如,有一个自平衡二叉树的想法。如果您将结构视为链接在一起的一堆节点,那么这些结构很容易理解。如果您尝试从数组/关联数组的角度考虑自平衡二叉树,您将遇到很多麻烦,因为它们往往有一个指向其父级的指针,这会创建看起来非常混乱的关联数组。

struct SelfBalancingBTreeNode
{
    value_type value;
    SelfBalancingBTreeNode* parent;
    SelfBalancingBTreeNode* left;
    SelfBalancingBTreeNode* right;
};

要对此建模,您需要有非常有趣的关联数组结构

leftNode = { value: 1, parent: null, left: null, right: null}
parentNode = value: 2, parent: null, left: leftNode, right: null}
leftNode['parent'] = parentNode

这会产生使用关联数组时通常不会想到的循环

【讨论】:

  • 谢谢,这很有帮助,我正在使用的语言不支持这样的纯结构,所以我 必须 使用数组、关联数组、或两者。不过,您的 SelfBalancingBTreeNode 结构确实看起来非常像 AA,而且我可以看到它也可能看起来像一个数组(访问起来会更快)。我想我现在知道的足够多,可以开始做一些编程来测试这里的概念了。
【解决方案2】:

二叉树:

     1
   /   \
  2     3
 / \   / \
4   5 6   7

可以表示为:

[1, 2, 3, 4, 5, 6, 7]

因此,位于索引 i 的节点的子节点位于索引 2i2i+1

或者可以表示为:

{1:[2,3], 2:[4,5], 3:[6,7]}

在某处引用根。

尝试:

      1
  a /   \ b
   2     3
a / \ b
 4   5

可以表示为:

{1:{a:2, b:3},
 2:{a:4, b:5},
 3:{},
 4:{},
 5:{}
}

【讨论】:

  • 每个讨论 b-trees 的网站都使用您使用的与数据结构没有明显关联的 ascii 线图,这正是我问这个问题的原因。我想我知道你要去哪里,但我有一些问题:数组 [1,2,3,4,5] 是一个 int 数组,而不是一个 AA 数组。所以你的意思可能是 {1:{a:2,b:3},2:{a:4,b:5}} 或 [{a:2,b:3},{a:4,b:5} ] 除了 {a:2,b:3} 将是数组的第零个元素,因此数组索引本身可能是 [{a:1,b:2},{c:3,d:4}]计数 [0,1,2,3,4] ?
  • @alphablender 我更希望将数字解释为对象。进行了更清晰的编辑。
猜你喜欢
  • 1970-01-01
  • 2011-11-28
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 2016-03-16
相关资源
最近更新 更多