【发布时间】:2015-02-13 05:09:42
【问题描述】:
我有一个类Tree,我想将其扩充为更专业的数据结构,例如Order_tree 和Interval_tree。这些扩充需要对Node 进行补充,例如尺寸信息,以及对某些算法的微小改动。
我想知道在性能、可读性和可维护性方面在 C++ 中实现增强的最佳方法。树不应该以多态方式使用。到目前为止,我尝试的是公开继承Tree,然后重载基本方法。 (我很抱歉成为面向对象编程的初学者)
template <typename T>
class Tree {
protected:
enum class Color : char {BLACK = 0, RED = 1};
struct Node {
T key;
Node *parent, *left, *right;
Color color;
Node() : color{Color::BLACK} {} // sentinel construction
Node(T val, Color col = Color::RED) : key{val}, parent{nil}, left{nil}, right{nil}, color{col} {}
};
using NP = typename Tree::Node*;
NP root {nil};
// nil sentinel
static NP nil;
// core utility algorithms...
};
template <typename T>
typename Tree<T>::NP Tree<T>::nil {new Node{}};
订单树
template <typename T>
class Order_tree : public Tree<T> {
using Color = typename Tree<T>::Color;
using Tree<T>::Tree; // inherit constructors
struct Order_node {
T key;
Order_node *parent, *left, *right;
size_t size; // # of descendent nodes including itself = left->size + right->size + 1
Color color;
Order_node() : size{0}, color{Color::BLACK} {} // sentinel construction
Order_node(T val, Color col = Color::RED) : key{val}, parent{nil}, left{nil}, right{nil}, size{1}, color{col} {}
};
using NP = typename Order_tree::Order_node*;
NP root {nil};
static NP nil;
// overloading on only the methods that need changing
};
template <typename T>
typename Order_tree<T>::NP Order_tree<T>::nil {new Order_node{}};
但是,这不能正常运行,因为现在我有 2 个根和 2 个 nil,所有基本方法都在基本根上工作,并且使用 Tree<T>::NP 而不是 Order_tree::NP 所以 Order_node 的大小属性不能使用。
一种方法是复制粘贴代码,这是非常难以维护的。我认为另一种方法是在 T 和 NP 上模板 Tree,以便 Order_tree 是别名 using Order_tree = Tree<Order_node> 并在节点上专门化树。
【问题讨论】:
-
将各种
tree类的T模板参数作为它们应该存储在每个节点中的结构更有意义,包括您当前正在考虑的value和“增强”数据。如果您希望T数据类型的特定部分充当键,您可以要求将该字段称为key,对于key_type;有一个typedef或任何其他支持您的预期客户端使用的东西;或者,您可以为密钥设置第二个模板参数,就像std::map所做的那样。 -
这会是一个额外的间接级别吗(在可读性和性能方面)? (要访问密钥,您必须说
node->data->key假设节点的有效负载是T data其中您建议的数据将是一个至少包含一个密钥的结构。
标签: c++ templates inheritance binary-search-tree