【问题标题】:Javascript tree traversal function errorJavascript树遍历函数错误
【发布时间】:2018-01-31 12:17:07
【问题描述】:

我正在熟悉 javascript 环境。我尝试实现一个对树进行中序遍历的函数,但是我遇到了一个错误。下面是我的代码。

我创建了一个Node 类,它定义了节点对象的属性。 在我的Tree 类中,构造函数定义了根属性。当我以根为参数调用 Inorder 函数时,编译器在 -->Inorder(root.left) 行上抛出一个错误,显示 -- Inorder is not defined--

我做错了什么?

class Tree {


    constructor(root) {

        this.root = root;
    }


    Inorder(root) {

        if (root == null) {
            return;

        }

        Inorder(root.left);
        console.log(root.data);
        Inorder(root.right);


    }

}


class Node {

    constructor(data) {

        this.data = data;
        this.left = null;
        this.right = null;

    }

}


const obj = new Node(5);
obj.left = new Node(10);
obj.right = new Node(15);
obj.left.left = new Node(16);
obj.right.right = new Node(17);


const tree = new Tree(obj);
console.log(tree.root.data);
tree.Inorder(tree.root);

【问题讨论】:

    标签: javascript data-structures ecmascript-6


    【解决方案1】:

    在 Tree 类的 Inorder 函数中,在前面带有“this”的内部 Inorder 调用。例如:this.Inorder(left);

    【讨论】:

      【解决方案2】:

      您对 Inorder 方法的调用需要在实例或类上运行,因为它仅作为类 Tree 的实例方法存在。看例子:

      class Tree {
          constructor(root) {
              this.root = root;
          }
      
          Inorder(root) {
              if (root == null) {
                  return;
              }
      
              // HERE:
              this.Inorder(root.left);
      
              console.log(root.data);
      
              // And HERE:
              this.Inorder(root.right);
          }
      }
      
      
      class Node {
          constructor(data) {
              this.data = data;
              this.left = null;
              this.right = null;
          }
      }
      
      const obj = new Node(5);
      obj.left = new Node(10);
      obj.right = new Node(15);
      obj.left.left = new Node(16);
      obj.right.right = new Node(17);
      
      
      const tree = new Tree(obj);
      console.log(tree.root.data);
      tree.Inorder(tree.root);
      

      已编辑:静态方法对您的需要没有意义,因此我将其从答案中删除

      编辑 2:添加一个 sn-p 显示递归函数的优化。

      请注意,现在,在递归部分,该方法可以是静态的,因为它不需要了解实例数据。它可以独立于调用它的树从根节点运行。

      如果您要使用大量实例,这将有助于优化内存使用,因为该方法仅在 Tree 类本身上定义。

      class Tree {
        constructor(root) {
          this.root = root;
        }
      
        // Inorder method doesn't need a root argument now
        // It uses instance's own root
        Inorder() {
          // Fire up the recursion
          Tree._Inorder(this.root);
        }
      
        // Private part for the Inorder method's recursion
        // It can be static since it will receive the root 
        // for each iteration
        static _Inorder(root) {
          if (root == null) {
            return;
          }
      
          Tree._Inorder(root.left);
      
          console.log(root.data);
      
          Tree._Inorder(root.right);
        }
      }
      
      
      class Node {
        constructor(data) {
          this.data = data;
          this.left = null;
          this.right = null;
        }
      }
      
      const obj = new Node(5);
      obj.left = new Node(10);
      obj.right = new Node(15);
      obj.left.left = new Node(16);
      obj.right.right = new Node(17);
      
      const tree = new Tree(obj);
      console.log("Tree created with root:", tree.root.data);
      
      // Now we can call the inorder list for the tree 
      // without explicitely specifying the root node
      tree.Inorder();

      【讨论】:

      • 意识到我的错误。所以我猜在这种情况下'this'指的是'tree'对象,因为它是按顺序调用函数的对象?
      • @batman007 你是对的,在类中定义的非静态方法将在调用它们的实例的上下文中执行。因此,当您在最后一行调用 tree.Inorder(tree.root) 时,您正在调用 tree 实例上的方法。这意味着您实际上不需要提供根,因为它将是当前树的根。由于该方法是递归的,因此您可以将其拆分为已有的公共部分和用于递归的私有部分,后者实际上接受根元素作为参数。如果有帮助,我可以用实际代码扩展答案;)
      • 能否请您添加代码 sn-p 以供进一步参考。那真的很有帮助。
      • 添加自定义,希望有用!
      • @batman007 没错。方法_Inorder 属于Tree 类,不属于Tree 的任何特定instance。但是,在 javascript 中,这在内存方面并没有太大区别,因为它处理实例方法的方式是通过对象的 prototype 来定义的。当调用实例方法时,实际调用的是 prototype 方法,this 的上下文设置为调用者实例。更多细节在这里:stackoverflow.com/questions/34898166/…
      猜你喜欢
      • 2013-08-22
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 2019-08-02
      • 2014-12-14
      相关资源
      最近更新 更多