【问题标题】:Function doesn't return default value函数不返回默认值
【发布时间】:2019-02-22 06:03:33
【问题描述】:

这是我的代码:

bool BinarySearchTree::CheckIfTreeIsBinary(){
    bool isBinary=true;
    isBinary=CheckIfTreeIsBinaryPrivate(root); // So if my tree is binary, this function does not return anything
                                               // and isBinary should remain true, but it is false.
    return isBinary;
}

bool BinarySearchTree::CheckIfTreeIsBinaryPrivate(nodePtr Ptr){ 
    if(Ptr->left!=NULL){
        CheckIfTreeIsBinaryPrivate(Ptr->left);
    }

    if(Ptr->left!=NULL){
        if(Ptr->data<Ptr->left->data)
            return false; // possibility 1 to return false
    }

    if(Ptr->right!=NULL){
        if(Ptr->data>Ptr->right->data)
            return false; // possibility 2 to return false
    }

    if(Ptr->right!=NULL){
        CheckIfTreeIsBinaryPrivate(Ptr->right);
    }
}

在我的函数CheckIfTreeIsBinary 中,我将布尔值isBinary 设置为true 作为默认值。之后,将 isBinary 分配给函数 CheckIfTreeIsBinaryPrivate,如果树是二叉树,它将不返回任何内容。
问题是,如果树是二叉树,函数 CheckIfTreeIsBinaryPrivate 不会返回任何内容,但最终 isBinary 为 false。

【问题讨论】:

  • 你没有从CheckIfTreeIsBinaryPrivate返回任何东西。
  • @juanchopanza - 是的,完全正确。但我希望我的 isBinary 保持真实。这可能吗?
  • 似乎您将BinarySearchTree 类成员变量与CheckIfTreeIsBinary 函数混淆了。 isBinary 变量只会在 CheckIfTreeIsBinaryPrivate 返回时更改。如果函数指定返回类型为bool,则必须返回true 或false;不返回任何东西不是您应该做的事情(我认为这是“未定义的行为”)。考虑写下你想要做什么,然后你打算如何去做。查看它是否与您的代码实际执行的操作相匹配(例如,定义需要满足哪些条件,这意味着它是一棵二叉树)。
  • “问题是函数 CheckIfTreeIsBinaryPrivate 没有返回任何东西” ...是的,这就是问题所在,只要确保在每条路径上都返回就可以了。不太清楚问题是什么,因为您似乎已经知道答案了

标签: c++ recursion binary-tree


【解决方案1】:

问题在于CheckIfTreeIsBinaryPrivate 确实不在所有程序控制路径上都有明确的return 值。

这意味着你的程序的行为是未定义的。

您的编译器会警告您这一点,您的工作就是注意这些警告。

【讨论】:

    【解决方案2】:

    您的递归逻辑不正确。函数中的所有路径都应该返回一个值,并且您应该始终检查对CheckIfTreeIsBinaryPrivate 的递归调用的返回值。没有“价值保持不变”的概念。这是我认为您正在努力实现的目标,但它非常复杂。

    bool BinarySearchTree::CheckIfTreeIsBinaryPrivate(nodePtr Ptr) { 
        return
            // check the left sub tree is ok
            (Ptr->left == NULL ||                 // NULL is ok OR
                (Ptr->data >= Ptr->left->data &&  // data >= left->data && left is ok
                     CheckIfTreeIsBinaryPrivate(Ptr->left))) &&
            // and check the right sub tree is ok
            (Ptr->right == NULL ||                // NULL is ok OR
                (Ptr->data <= Ptr->right->data && // data <= right->data && right is ok
                     CheckIfTreeIsBinaryPrivate(Ptr->right)));
    }
    

    【讨论】:

      【解决方案3】:

      我想我明白你的误解在哪里了;您期望 isBinary 仅在 CheckIfTreeIsBinaryPrivate 返回值时更新。

      这不是它的工作原理 - 具有非void 返回类型的函数必须始终返回 something。
      如果函数没有显式返回任何内容(例如,到达函数末尾),则程序具有未定义的行为。

      您无法确定函数是否返回任何内容,并且您必须在通过该函数的每条路径上返回一些内容。

      你可以用一个大表情来做到这一点,

      bool BinarySearchTree::isBST(nodePtr Ptr){
          return Ptr == nullptr
              || (   (Ptr->left == nullptr || (Ptr->left->data < Ptr->data && isBST(Ptr->left)))
                  && (Ptr->right == nullptr || (Ptr->right->data > Ptr->data && isBST(Ptr->right))));
      }
      

      或一块一块地:

      bool BinarySearchTree::isBST(nodePtr Ptr){
          // An empty tree is a BST.
          if (Ptr == nullptr)
              return true;
          // If the left subtree is not a BST, neither is the entire tree.
          else if (Ptr->left != nullptr && (Ptr->left->data > Ptr->data || !isBST(Ptr->left)))
              return false;
          // If the right subtree is not a BST, neither is the entire tree.
          else if (Ptr->right != nullptr && (Ptr->right->data < Ptr->data || !isBST(Ptr->right)))
              return false;
          // All tests passed.
          else
              return true;
      }
      

      【讨论】:

      • 迂腐点:从技术上讲,如果调用者使用返回值,则无法return 的函数只会引入未定义的行为。每N1570, 5.9.1 Function definitions, item #12:“如果到达终止函数的},并且调用者使用函数调用的值,则行为未定义。”在这种情况下,调用者使用了返回值,所以你的观点是正确的,只是注意到有一个非void 函数在奇怪的情况下无法返回任何东西是合法的(如果奇怪的话)。
      【解决方案4】:

      在CheckIfTreeIsBinaryPrivate() 中再添加一个基本条件以设置为真, 因为一旦你将isBinary 分配给CheckIfTreeIsBinaryPrivate(),它会默认设置为false,你需要一个返回值来获得true。

      【讨论】:

        猜你喜欢
        • 2012-08-03
        • 1970-01-01
        • 2020-12-22
        • 1970-01-01
        • 1970-01-01
        • 2013-02-18
        • 2011-12-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多