Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;:指向数据成员或特征的指针? 我在C++中使用了一些二叉树算法,并试图尽可能地编写通用代码。特别是,我希望我的函数(算法)能够对任何(当然,在某种程度上)树状数据结构进行操作_C++_Templates_C++11 - Fatal编程技术网

C++;:指向数据成员或特征的指针? 我在C++中使用了一些二叉树算法,并试图尽可能地编写通用代码。特别是,我希望我的函数(算法)能够对任何(当然,在某种程度上)树状数据结构进行操作

C++;:指向数据成员或特征的指针? 我在C++中使用了一些二叉树算法,并试图尽可能地编写通用代码。特别是,我希望我的函数(算法)能够对任何(当然,在某种程度上)树状数据结构进行操作,c++,templates,c++11,C++,Templates,C++11,树节点结构可以用不同的方式定义,例如: struct binary_tree_node { int data; struct binary_tree_node *left; struct binary_tree_node *right; }; 或者像这样: struct binary_tree_node2 { long key; struct binary_tree_node2 *first_child; struct binary_tree_n

树节点结构可以用不同的方式定义,例如:

struct binary_tree_node
{
    int data;
    struct binary_tree_node *left;
    struct binary_tree_node *right;
};
或者像这样:

struct binary_tree_node2
{
    long key;
    struct binary_tree_node2 *first_child;
    struct binary_tree_node2 *second_child;
};
或者其他的,但和这个模式很相似。 因此,我希望我的函数/算法能够处理这些或类似的数据结构

例如,以下是我如何定义一个简单函数:

template <typename TreeNode, typename DataType = typename TreeNode::data_type>
TreeNode*
binary_tree_new_node(DataType value = DataType(),
                     DataType  TreeNode::* data  = &TreeNode::data,
                     TreeNode* TreeNode::* left  = &TreeNode::left,
                     TreeNode* TreeNode::* right = &TreeNode::right)
{
    TreeNode *newnode = new TreeNode();
    newnode->*data  = value;
    newnode->*left  = nullptr;
    newnode->*right = nullptr;
    return newnode;
}
这里有哪些可用选项? 这有什么意义吗?:)


提前感谢

STL集合库的工作方式是树库的作者将提供节点类,这样模板的所有用户需要做的就是提供数据。另一个你想要的选择是侵入式的数据结构(这对于谷歌来说是一个很好的概念术语)。对于这些成员,您有两个选择,第一个是要求数据成员为左、右和右数据。其次,需要具有特定名称的访问函数,以便模板可以找到它们。第三,需要将functor作为模板参数传入,以便您可以使用它们查找所需的数据。我个人认为STL方法最不混乱,其次是函子方法。

为了使算法尽可能通用,我建议使用函子。您的二叉树新节点如下所示

template<typename G, typename L, typename R, typename AT, typename AD, typename D>
auto binary_tree_new_node(
    G generator,
    L left,
    R right,
    AT assign_tree,
    AD assign_data,
    D data) ->decltype( generator() )
{
    auto  tree = generator();
    auto& l    = left(tree);
    auto& r    = right(tree);
    assign_data(tree, data);
    assign_tree(l, nullptr);
    assign_tree(r, nullptr);
    return tree;
}

除了支持不同名称的字段外,您的代码似乎不太通用。它不支持使用
unique\u ptr
shared\u ptr
存储其子级的树,也不支持子级使用
弱\u ptr
指向其父级的树,也不支持树将其子级存储在
std::vector
中的树,或其他无数变体。我不想直接在树上操作,而是想找到一些原始操作并对它们进行操作。那么这些原始操作是否依赖于
特征
任何类型…@Yakk*\u ptr有什么问题
std::vector
使它不仅仅是一个二叉树。关于基本操作的想法听起来不错,但对于基本的二叉树,它只是遵循左或右子级。因此,我指出了您的设计存在缺陷的4种方式(
唯一的\u ptr
共享的\u ptr
,当它们被修改时想要做某事的节点,可能的指针存储直到需要时才存在),你已经回应了其中一个。其他3个不足以扔掉你的设计吗?对于
std::vector
,N元树支持所有的二叉树操作(set/get first child、set/get second child、set/get node data),因此一个好的二叉树抽象应该能够将创建一个N元树包装为二进制:您不能,这表明你的抽象性很差。@Yakk我不是想在这里建立一个完美的抽象,而是问如何改进一个特定的东西。不过,感谢您的想法和反馈,我真的很感激。我不会完全同意“树库的作者将提供节点类”这一部分。通过这样做,如果必须使用node类,作者将算法绑定到该类,这实际上与将算法定义为该类的方法相同,这(至少据我所知)不是STL/boost或类似LIB应该采用的方式。@alveko您标准列表的用户从未定义列表节点。这同样适用于Map或需要使用节点的任何其他标准容器。节点是在容器内部定义的。如果您在VS2012中,请打开列表标题并搜索struct\u list\u节点。它为数据定义了一个节点结构,其中包含_Next _Prev和_Myval。
template<typename G, typename L, typename R, typename AT, typename AD, typename D>
auto binary_tree_new_node(
    G generator,
    L left,
    R right,
    AT assign_tree,
    AD assign_data,
    D data) ->decltype( generator() )
{
    auto  tree = generator();
    auto& l    = left(tree);
    auto& r    = right(tree);
    assign_data(tree, data);
    assign_tree(l, nullptr);
    assign_tree(r, nullptr);
    return tree;
}
// WARNING!!! Very dangerous code!!!

binary_tree_node* generator()
{
    return new binary_tree_node;
}

binary_tree_node*& left(binary_tree_node* tree)
{
    return tree->left;
}

binary_tree_node*& right(binary_tree_node* tree)
{
    return tree->right;
}

void assign_data(binary_tree_node* node, int data)
{
    node->data = data;
}

void assign_tree(binary_tree_node*& node, binary_tree_node* data)
{
    node = data;
}