【问题标题】:Question about the execution of a BST JS recursive function关于BST JS递归函数执行的问题
【发布时间】:2021-02-13 14:55:27
【问题描述】:

我想出了一个 BST 验证问题的解决方案。我先把问题和我写的代码列出来,然后告诉你执行的哪一部分我不明白。

// --- Directions
/* Given a node, validate the binary search tree,
   ensuring that every node's left hand child is
   less than the parent node's value, and that
   every node's right hand child is greater than
   the parent. e.g.:
 
   10
 5   15
0     20 
 999    
        */

class Node {
  constructor(data) {
    this.data = data;
    this.left = null;
    this.right = null;
  }

  insert(data) {
    if (data < this.data && this.left) {
      this.left.insert(data);
    } else if (data < this.data) {
      this.left = new Node(data);
    } else if (data > this.data && this.right) {
      this.right.insert(data);
    } else if (data > this.data) {
      this.right = new Node(data);
    }
  }
}

function validate(node, min = null, max = null) {
  if (node.right) {
    min = node.data;
    if (node.right && node.right.data > min) {
      return validate(node.right, min, max);
    } else if (node.right && node.right.data < min) {
      return false;
    }
  }
  if (node.left) {
    max = node.data;
    if (node.left && node.left.data < max) {
      return validate(node.left, min, max);
    } else if (node.left && node.left.data > max) {
      return false;
    }
  }
  return true;
}

const n = new Node(10);
n.insert(5);
n.insert(15);
n.insert(0);
n.insert(20);
n.left.left.left = new Node(999);

console.log(validate(n));

我所期望的是,该函数将首先验证树的右侧,然后开始在左侧工作。但发生的情况是,一旦它检查右侧,它只会从递归调用中返回 true。它返回到 n 的初始值,但不检查树左侧的第二个 if 语句,它只是退出函数。

我假设它可能会退出,因为初始函数调用最终通过递归第一个 if 语句返回 true,因此它不会打扰检查第二个。如果是这种情况,有没有办法让函数也检查第二个 if 语句,而不是在第一个之后退出函数?

【问题讨论】:

  • 第一部分总是执行return,所以第二部分是死代码(当node.right为真时)。

标签: javascript validation recursion binary-search-tree binary-search


【解决方案1】:

确实,您的代码的第一部分(如果node.right 是真实的)将总是执行return,因此您的代码的第二部分也无法获得执行。

当结果为false时返回是可以的,但在其他情况下,你应该返回:

function validate(node, min = null, max = null) {
  if (node.right) {
    min = node.data;
    if (node.right && node.right.data > min) {
      if (!validate(node.right, min, max)) return false; // <---
    } else if (node.right && node.right.data < min) {
      return false;
    }
  }
  if (node.left) {
    max = node.data;
    if (node.left && node.left.data < max) {
      return validate(node.left, min, max);
    } else if (node.left && node.left.data > max) {
      return false;
    }
  }
  return true;
}

我刚刚修改了您的问题所必需的内容,但是您的代码中有很多检查重复了已经断言的内容。例如,当您在第一个 if 块中时,无需再次检查 node.right 是否为真。因此,您可以将代码简化为:

function validate(node, min = null, max = null) {
  if (node.right && (node.right.data < node.data || 
        !validate(node.right, node.data, max))) return false;
  if (node.left && (node.left.data > node.data ||
        !validate(node.left, min, node.data))) return false;
  return true;
}

...这可能会更简化为只有一个返回语句,但我会留给你,-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 2020-05-10
    • 2021-12-14
    • 2020-03-21
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    相关资源
    最近更新 更多