【问题标题】:Vector based binary tree traversal基于向量的二叉树遍历
【发布时间】:2012-11-13 11:51:40
【问题描述】:

我有一个基于向量的二叉树,需要使用各种遍历方法对树中的每个值应用一个函数。使用递归函数很容易实现前序遍历,但我在使用中序遍历和后序遍历时遇到了麻烦。如果有人能帮忙就太好了!

我应该包括的一些额外信息: 我正在使用一个节点向量,每个节点都包含一个布尔变量,说明该节点是否已填充和一个模板化数据变量。每个节点都存储在索引“i”中,而其左子节点存储在索引“2i+1”,右子节点存储在索引“2i+2”。

为了对列表应用前序遍历,我首先处理了存储在索引 0 处的数据,然后调用了这个递归函数

template <typename Item, typename Key>
template <typename Function>
void BST<Item,Key>::preTraverse(int n, Function f) {
    if(tree[n].occupied == false) return;
    else {
        f(tree[n].data);
        preTraverse(2*i+1,f);
        preTraverse(2*i+2,f);
    }
}

两次以索引 1 和 2 开头作为我的“n”参数。

【问题讨论】:

  • 能否请您发布您设法正确的遍历代码?这将有助于我们更好地理解您过去在向量中“折叠”一棵树的方式。
  • 向量表示是否有效地是从左到右的最大填充定义? (即 [i] 的孩子在 [2i+1] 和 [2i+2] ?
  • "预购遍历很容易...但是我[遇到麻烦]预购...遍历"?也许你没有说出你想说的话。
  • 我在问题的编辑中添加了向量的代码和更多详细信息。我的意思是说 inorder 和 postorder 而不是 preorder 和 postorder。

标签: c++ vector binary-tree traversal preorder


【解决方案1】:

假设你的树是一个最大填充的左显性表示,那么你的数组中位置i 的任何给定点都会在位置2*i+12*i+2 有孩子。琐碎的行走:

Node   Children
=====  ===========
ar[0]: ar[1], ar[2]
ar[1]: ar[3], ar[4]
ar[2]: ar[5], ar[6]
ar[3]: ar[7], ar[8]
ar[4]: ar[9], ar[10] etc...

鉴于此定义,preorder、postorder 和 in-order 都可以通过简单的索引转发和一些检查“占用”标志来完成。以下模板假定类型 T 是具有“占用”成员的结构类型。

template<typename T>
void preorder(const T ar[], size_t i, size_t count, void (&visit)(const T&))
{
    if (i>=count || !ar[i].occupied)
        return;

    visit(ar[i]);
    preorder(ar, 2*i+1, count, visit);
    preorder(ar, 2*(i+1), count, visit);
}

template<typename T>
void inorder(const T ar[], size_t i, size_t count, void (&visit)(const T&))
{
    if (i>=count || !ar[i].occupied)
        return;

    inorder(ar, 2*i+1, count, visit);
    visit(ar[i]);
    inorder(ar, 2*(i+1), count, visit);
}

template<typename T>
void postorder(const T ar[], size_t i, size_t count, void (&visit)(const T&))
{
    if (i>=count || !ar[i].occupied)
        return;

    postorder(ar, 2*i+1, count, visit);
    postorder(ar, 2*(i+1), count, visit);
    visit(ar[i]);
}

【讨论】:

  • 你的postorder函数错了,应该是postorder(ar, 2*i+1, visit);postorder(ar, 2*i+2, visit);,然后是visit(ar[i]);
【解决方案2】:

预购:

do something with the value
f(go to the left)
f(go to the right)

顺序:

f(go to the left)
do something with the value
f(go to the right)

后购:

f(go to the left)
f(go to the right)
do something with the value

【讨论】:

    猜你喜欢
    • 2012-01-01
    • 2022-11-11
    • 1970-01-01
    • 2021-11-20
    • 2022-01-11
    • 2021-03-08
    • 2020-01-15
    • 1970-01-01
    相关资源
    最近更新 更多