2017-10-17 123 views
-1

为节点实现了一个C++类,但以某种方式在删除节点时仍然出现错误。C++将已删除节点的子节点移到树中的父节点

一般algorithim是这样的:

  • 设定孩子的PARENT_到PARENT_
  • 孩子添加到父
  • 的孩子从这个节点
  • 的孩子取出孩子

这里是我的类文件:

template <typename E> 
class TNode{ 

    ... 

bool remove(){ 
      if ((parent_==NULL) && (children_.size()>0)){ 
       cout << "can't remove the root if it has children\n"; 
       return false; 
      } 
      else{ 

       parent_->children_.erase(std::remove(parent_->children_.begin(), parent_->children_.end(), this), parent_->children_.end()); 

       for (int i=children_.size()-1;i>=0; i--){ 

        //my error is happening here 

        parent_ = parent_ -> children_; 
        this = children_ -> this; 
        parent_ = parent_ -> this; 
       } 

       //delete (deallocate memory of) this node 
       delete this; 
       return true; 
      } 
     } 

     friend class gTree<E>; 

     private: 
     E data_; 
     gTNode<E>* parent_; 
     std::vector<gTNode<E>*> children_; 
    }; 

有人能指引我正确的方向吗?

编辑的错误是这样的:

gTree.h: In member function ‘bool gTNode<E>::remove()’: 
gTree.h:50:29: error: expected unqualified-id before ‘this’ 
     this = children_ -> this; 
          ^
gTree.h:50:29: error: expected ‘;’ before ‘this’ 
gTree.h:51:30: error: expected unqualified-id before ‘this’ 
     parent_ = parent_ -> this; 
          ^
gTree.h:51:30: error: expected ‘;’ before ‘this’ 
+0

见上 – nickoba

回答

0

的实现是完全错误的。我在代码中看到了几个错误。如果在没有子节点的根节点上调用remove(),则访问NULL parent_。并且循环未正确占用vector::size()未签名。只是一般的语法错误。

尝试一些更喜欢这个:

template <typename E> 
class gTNode 
{ 
    ... 
    bool remove() 
    { 
     if (parent_) 
     { 
      auto iter = std::find(parent_->children_.begin(), parent_->children_.end(), this); 
      auto index = std::distance(parent_->children_.begin(), iter); 
      parent_->children_.erase(iter); 
      if (!children_.empty()) 
      { 
       parent_->children.reserve(parent_->children_.size() + children_.size()); 
       parent_->children_.insert(parent_->children.begin() + index, children_.begin(), children_.end()); 
       for (auto *child : children_) 
        child->parent_ = parent_; 
       children_.clear(); 
      } 
     }  
     else if (!children_.empty()) 
     { 
      cout << "can't remove the root if it has children\n"; 
      return false; 
     } 

     //delete (deallocate memory of) this node 
     delete this; 
     return true; 
    } 

    friend class gTree<E>; 

private: 
    E data_; 
    gTNode<E>* parent_; 
    std::vector<gTNode<E>*> children_; 
}; 
+0

@nickoba代码我发现并没有改变孩子的顺序编辑,所以输入必须是在要开始使用 –

+0

有删除节点时更改顺序的方法? – nickoba

+0

@nickoba当然,你可以使用任何你想要的顺序。但为什么要改变顺序呢?除非儿童应该被分类。 –