用于维护树木集合的程序设计

时间:2014-04-09 19:22:17

标签: c++ class oop tree

我正在尝试维护一组完美的,堆有序的二叉树: enter image description here

(对不起)。

所以,我认为创建一个 heapNode 类型,包含相关的子/父指针并持有一个元素,以及一个 heap 类型,它将实现这些操作在树上,会是直截了当的。至少,如果我只担心一棵树,我就会这样做。问题是,给定指向任何树中的节点的指针,我需要能够删除该节点。但是,只有指针,我无法弄清楚我将如何知道要调用的 heap 实例。

我的想法是,我没有这样的类型,只有节点,然后是某种类型的修饰符类型,它将实现所有树木作业。这个修饰符唯一能够知道的是如何操作 heapNodes (更改链接等)。我认为修饰符类型只是静态方法的集合,也许只是普通C函数的集合。

对这个问题有什么看法?我猜这是一个更普遍的问题:给定一个类的某个(数据)成员的引用,你如何轻松访问它上面的可用操作?我在C ++中这样做,我不太清楚。我很喜欢C。感谢。

1 个答案:

答案 0 :(得分:0)

你从哪里获得指向树木的指针?恕我直言,这违反了你的树集合类的封装(如果没有,这可能是问题),并且是缺少抽象的标志。保持你的内部私密。

你知道你可以使用数组建模堆而不使用通过指针链接的节点吗?在C ++中,STL提供了执行此操作的功能。

template<typename T> class Forest {
public:
// functions to do something with the heap,
// but do not leak internals.
void do_something(T const& x) {
    // pick a heap and add an element
    mHeaps[0].push(x);
}

private:
// simple wrapper around STL heap functions
class Heap {
public:
    void push(T const& x) {
        mData.push_back(x);
        std::push_heap(mData.begin(), mData.end());
    }

    T pop() {
        std::pop_heap(mData.begin(), mData.end());
        T const tmp(mData.back());
        mData.pop_back();
    }

    private:
        std::vector<T> mData;
    };

std::vector<Heap> mHeaps;
};

如果需要迭代,请实现自定义迭代器迭代所有堆,但不要泄漏内部。客户不应该依赖于实施知识,例如堆积的实施方式。

如评论中所述,您正在使用堆实现优先级队列(cphstl.dk/Paper/TOCS-2011/journal.pdf)。我会建议这样的设计:

  • 一个优先级队列类,它存储堆的集合并具有第13页中提到的不变量(这对于在调试操作之前和之后检查是很好的)。它还存储数字系统表示。让我们说优先级队列保留一个向量成员。
  • 表示数字系统的类。这通过存储迭代器实现了向量中映射的映射。
  • 表示单个堆的类,其中包含要添加,删除和元素的操作以及与其他堆合并的操作。您可以查看std :: map以获取树结构的示例。

这些元素几乎可以单独实施和测试。优先级队列的客户端看不到任何实现。