Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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++_Algorithm_Binary Tree_Smart Pointers - Fatal编程技术网

C++ 从向量创建树

C++ 从向量创建树,c++,algorithm,binary-tree,smart-pointers,C++,Algorithm,Binary Tree,Smart Pointers,我在做一个符号计算器。但是为了给出一个小的可验证的例子,我把它分解为下面的例子,一开始可能看起来很奇怪 我有一个点{1,4,3,8,5,7}的列表,我迭代了这些点。我在每次迭代中读到两点。 我想让这段代码做的是: 迭代1:没有树,所以我们创建一个。我们在4号上保留了一份参考资料 4 / 1 迭代2:8比上一次引用(4)大。所以我们 8 / 3 一个4岁的孩子,并在8岁时留下一份参考资料 4 / \ 1 8 / 3 迭代3:7

我在做一个符号计算器。但是为了给出一个小的可验证的例子,我把它分解为下面的例子,一开始可能看起来很奇怪

我有一个点{1,4,3,8,5,7}的列表,我迭代了这些点。我在每次迭代中读到两点。 我想让这段代码做的是:
迭代1:没有树,所以我们创建一个。我们在4号上保留了一份参考资料

  4
 /
1
迭代2:8比上一次引用(4)大。所以我们

  8
 /
3
一个4岁的孩子,并在8岁时留下一份参考资料

    4
  /   \
 1      8
       /
      3
迭代3:7小于最后一个引用(8),因此我们返回,直到找到小于4的数字(或到达根)。然后我们创建节点

 7
  \
   5
并将最后一个引用作为左子项添加到此

     7
   /   \
  4      5
 /  \
1    8
    /
   3
请注意:我不关心这里的特殊情况等。我敢肯定,一旦我成功了,我可以自己解决这个问题。

这是我的树类:

#ifndef NODE_H
#define NODE_H

#include <memory>
#include <string>

template<typename T>
class Node : public std::enable_shared_from_this< Node<T> >{
    public:
        typedef std::shared_ptr< Node<T> > NodePtr;
        typedef std::weak_ptr< Node<T> > NodeWPtr;

        T data;
        NodePtr left, right;
        NodeWPtr parent;

        Node(){}
        Node(const T& data) : data(data){}
        Node(const T& data, NodeWPtr parent) : data(data), parent(parent){}
        Node(const T& data, NodeWPtr parent, NodePtr& left) : data(data), parent(parent), left(left){
            left->parent = this->shared_from_this();
        }
        Node(const Node& n) : data(n.data), left(n.left), right(n.right){}
        Node& operator=(const Node&) = delete;
        ~Node() = default;

        NodePtr findRoot(){
            if( parent.lock() ){
                return parent.lock()->findRoot();
            }
            return this->shared_from_this();
        }

        void print(int indent=0){
            std::cout << data << std::endl;
            std::cout << std::string(2*indent+2, '-') << "L: ";
            if( left ){
                left->print(indent+1);
            }
            std::cout << std::endl;
            std::cout << std::string(2*indent+2, '-') << "R: ";
            if( right ){
                right->print(indent+1);
            }
            if( indent==0 ) std::cout << std::endl;
        }
};

#endif // NODE_H
\ifndef节点
#定义节点
#包括
#包括
模板
类节点:public std::从\u this{
公众:
typedef std::shared_ptrNodePtr;
typedef std::弱_ptrNodeWPtr;
T数据;
不接受左,右;
NodeWPtr父代;
节点(){}
节点(const T&data):数据(data){}
节点(const T&data,NodeWPtr parent):数据(data),父(parent){
节点(常量T和数据、NodeWPtr父节点、NodePtr和左节点):数据(数据)、父节点(父节点)、左节点(左){
左->父=此->共享来自此()的\u;
}
节点(const Node&n):数据(n.data)、左(n.left)、右(n.right){
节点和运算符=(const Node&)=删除;
~Node()=默认值;
NodePtr findRoot(){
if(parent.lock()){
返回parent.lock()->findRoot();
}
从_this()返回此->共享_;
}
无效打印(整数缩进=0){
std::cout数据){
NodePtr newNode=std::使_共享(Node(list.at(i+1));
newNode->left=std::make_shared(Node(list.at(i));
last->right=newNode;
newNode->parent=last;
newNode->findRoot()->print();
last=newNode;
last->findRoot()->print();
}否则{
而(!last->parent.expired()&&last->dataparent.lock();
}
NodePtr newNode=std::使_共享(Node(list.at(i+1));
newNode->right=std::make_shared(Node(list.at(i));
新建节点->左=最后一个;
last->parent=newNode;
last=newNode;
}
}
last->findRoot()->print();
}

不知何故,当我在第二次迭代中复制它时,4-1分支被删除了。在第一次打印时,它仍然存在,但在复印后,它就消失了。

问题在于以下几行

newNode->parent = last;
newNode->findRoot()->print();
last = newNode;
最初,只有shared_ptr
last
指向节点4。将
newNode
分配给
last
后,不再有指向节点4的共享ptr。这导致节点8中的父节点失效。因此,当您调用
last->findRoot()
(这里最后一个是节点8)时,它无法返回节点4


您的数据结构确保每个节点(除根节点外)都由至少1个共享的ptr(其父节点)指向。因此,您需要手动将共享的\u ptr保存到根节点。

哦,这是因为父节点是弱\u ptr吗?我有点假设,它仍然指向4,所以我在这里是安全的是的,弱ptr不会延长对象的生命周期。
newNode->parent = last;
newNode->findRoot()->print();
last = newNode;