【问题标题】:Coding remove() function for a Binary Tree为二叉树编写 remove() 函数
【发布时间】:2020-02-20 06:40:06
【问题描述】:

我在一个数据结构类中,我们必须编写一个二叉树(不是二叉搜索树)。我已经完成了 90% 的工作,但我的 remove() 函数无法正常工作。

作为参考,我们正在创建一个必须具有以下功能的类 BinaryTree

template <class ItemType>
class BinaryTree {
    private:
     std::shared_ptr<BinaryNode<ItemType>> rootptr;

    protected:
     // Removes the target value from the tree
     virtual std::shared_ptr<BinaryNode<ItemType>
     removeValue(std::shared_ptr<BinaryNode<ItemType>> subTreePtr,
                  const ItemType& target, bool isSuccessful);

     // Copies values up the tree to overwrite value in current
     // node until a leaf is reached; the leaf is then removed,
     // since its value is stored in the parent.
     std::shared_ptr<BinaryNode<ItemType>>
     moveValuesUpTree(std::shared_ptr<BinaryNode<ItemType>>
                      subTreePtr);

      // other { working } methods

    public:
     // Removes specified item from the tree
     bool remove(const ItemType& data);

     // other { working } methods
}

BinaryNode 类的接口(提供给我们)是:

template <class ItemType>
class BinaryNode {
    private:
     ItemType item;
     std::shared_ptr<BinaryNode<ItemType>> leftChildPtr;
     std::shared_ptr<BinaryNode<ItemType>> rightChildPtr;
    public:
     // returns true if node has no children
     bool isLeaf() const;

     // other typical methods (constructors, getters, setters)
}

到目前为止,我已经为 moveValuesUpTree 函数尝试了以下实现:

std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::
    moveValuesUpTree(std::shared_ptr<BinaryNode<ItemType>>
                     subTreePtr) {

    if(subTreePtr) {
        if(!subTreePtr->isLeaf()) {
            if(subTreePtr->getLeftChildPtr()) {
                subTreePtr->setItem(subTreePtr->getLeftChildPtr()
                                    ->getItem());
                moveValuesUpTree(subTreePtr->getLeftChildPtr());
            } else if(subTreePtr->getRightChildPtr()) {
                subTreePtr->setItem(subTreePtr->getRightChildPtr()
                                    ->getItem());
                moveValuesUpTree(subTreePtr->getRightChildPtr());
            } // end if
        } // end if
    } // end if
    return subTreePtr;
} // end moveValuesUpTree

此函数用于将值向上移动。我在想,在编写 removeValue() 函数时,我可以将要删除的节点的值移动到树的底部,然后将其删除(这样它总是一片叶子,你不必担心重新连接任何节点),但 moveValuesUpTree 函数会删除我想要删除的值。有没有办法在上面的递归 moveValuesUpTree 函数中保留这个值,然后将它存储在叶子中?或者有没有更好的方法来结合使用这两个受保护的方法来删除一个值?

谢谢!

编辑:moveValuesUpTree 函数不会删除节点——只是值。例如,在(后序)输出为 74625381 的树上调用 moveValuesUpTree(2) 将为 77645831。

【问题讨论】:

  • "...moveValuesUpTree 函数擦除了我想要删除的值。" 有什么问题?
  • @Beta 编辑帖子澄清
  • @BalsamicVinegar 哦,你的昵称,BalsamicVinegar +10 生命值并恢复 +1 法力。 :)
  • 我喜欢 90% 的工作总是最后一个 10% 就是问题所在。这几乎和最后 1% 一样糟糕。
  • 这是一个正确的算法吗?通常有一个旋转步骤。

标签: c++ recursion binary-tree


【解决方案1】:

不要将值移动到最后一个叶子然后删除叶子,而是在向上移动值时将其删除,因为此时您会找到叶子并知道它的确切位置。我的建议是测试当前节点的左或右子节点是否是叶子,如果是,则删除它,因为您已经在当前节点中移动了它的值。

std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::
moveValuesUpTree(std::shared_ptr<BinaryNode<ItemType>>subTreePtr) {

    if(subTreePtr) {
        if(!subTreePtr->isLeaf()) {
            if(subTreePtr->getLeftChildPtr()) {
                subTreePtr->setItem(subTreePtr->getLeftChildPtr()->getItem());

                if(subTreePtr->getLeftChildPtr()->isLeaf())
                    //Delete left child here
                else
                    moveValuesUpTree(subTreePtr->getLeftChildPtr());
              } else if(subTreePtr->getRightChildPtr()) {
                subTreePtr->setItem(subTreePtr->getRightChildPtr()->getItem());

                if(subTreePtr->getRightChildPtr()->isLeaf())
                    //Delete right child here
                else
                     moveValuesUpTree(subTreePtr->getRightChildPtr());
            } // end if
        } // end if
    } // end if
    return subTreePtr;
} // end moveValuesUpTree

【讨论】:

    【解决方案2】:

    感谢@Matriac,我通过编辑 moveValuesUpTree 解决了这个问题

    std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::
        moveValuesUpTree(std::shared_ptr<BinaryNode<ItemType>>
                         subTreePtr) {
    
        if(subTreePtr) {
            if(!subTreePtr->isLeaf()) {
                if(subTreePtr->getLeftChildPtr()) {
                    subTreePtr->setItem(subTreePtr->getLeftChildPtr()
                                        ->getItem());
                    if(subTreePtr->getLeftChildPtr()->isLeaf()) {
                        subTreePtr->setLeftChildPtr(nullptr);
                    } else {
                        moveValuesUpTree(subTreePtr->getLeftChildPtr());
                    }
                 } else if(subTreePtr->getRightChildPtr()) {
                subTreePtr->setItem(subTreePtr->getRightChildPtr()
                                    ->getItem());
                    if(subTreePtr->getRightChildPtr()->isLeaf()) {
                        subTreePtr->setRightChildPtr(nullptr);
                    } else {
                        moveValuesUpTree(subTreePtr->getRightChildPtr());
                    } // end if
                } // end if
            } // end if
        } // end if
        return subTreePtr;
    } // end moveValuesUpTree
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多