基于矢量的二叉树遍历

时间:2012-11-26 01:23:14

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

我有一个基于矢量的二叉树,需要使用各种遍历方法将函数应用于树中的每个值。使用递归函数很容易实现前序遍历,但是我在使用inorder和postorder遍历时也遇到了相同的问题。如果有人能提供帮助那就太棒了!

我应该包含的一些额外信息: 我正在使用节点向量,每个节点包含一个布尔变量,表明该节点是否已填充,以及模板化数据变量。每个节点存储在索引“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&amp;开始两次2作为我的“n”参数。

2 个答案:

答案 0 :(得分:3)

序:

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

答案 1 :(得分:2)

假设您的树是最大填充的左主导表示,那么位于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...

根据这个定义,预订,后序和有序都可以通过简单的索引转发和对“被占用”标志的一些检查来完成。以下模板假定类型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]);
}