2012-04-17 32 views
2

我正在创建一个程序来表示JavaScript中的二叉搜索树。我想要的是一种创建两个ptrs(左侧,右侧)为空的公共树节点的方法。这是我写的代码:
如何在javascript中创建自定义对象的常用常量实例?

var BST = function(data) { 
    if (data === null || data === undefined){ 
     this.data = null; 
     this.left = null; 
     this.right = null; 
    } 

    else{ 
     this.data = data; 
     this.left = new BST(null); 
     this.right = new BST(null); 
    } 
}; 

BST.prototype.insert = function(data) { 
    if (this.data === null){ 
     this.data = data; 
     this.left = new BST(null); 
     this.right = new BST(null); 
    } 
    else if (data < this.data) 
     this.left.insert(data); 
    else if (data > this.data) 
     this.right.insert(data); 
}; 

BST.prototype.inOrder = function(func) { 
    if (this.data !== null) { 
     this.left.inOrder(func); 
     func(this.data); 
     this.right.inOrder(func); 
    } 
}; 

在这里,我想与分配一空节点的所有空指针(如if(data === null || data === undefined)状态定义)。但是对于每个空节点,我不得不创建一个代表相同数据的新节点。 有没有办法分配给空节点的公共实例?
我用一个空节点,而不是原因只是用

else{ 
    this.data = data; 
    this.left = null; 
    this.right = null; 
} 

是在调用inOrder方法,在到达一个节点与left or right = null,它提供了TypeError,因为它试图从运行null.inOrder(func);this.left翻译到null
解决方法是修改inOrder函数,这将导致围绕每个语句的许多条件,即不是非常优雅的实现。
我也可以在对象的原型之外定义inOrder,并使它以树为参数,即inOder(tree,func),但我不想这样做。

此外,作为代码的第二个改进,请考虑insert方法;在null情况:

if (this.data === null){ 
    this.data = data; 
    this.left = new BST(null); 
    this.right = new BST(null); 
} 

,因为我无论如何都要覆盖每个条目,我想完全通过沿线的做一些重新分配这个节点到一个新的树:

if (this.data === null) 
    this = new BST(data); 

我意识到这对前者来说效率较低,但它仍然更加简洁。那么有什么办法可以这样做吗?

+0

您不能指定'this',而是需要操作父节点。 – Bergi 2012-04-17 18:23:16

回答

1

但是,每空节点,我不得不创建一个新的节点表示相同的数据。有没有办法分配给空节点的公共实例?

是的,但这会破坏你的代码。想想看:当你在该节点实例上调用insert方法时会发生什么? ...

至于第二个问题,你不能使用你现有的模型进行优化。没有这样的东西就地替换对象(there is in C#)。

我认为当前的代码是好的,但我个人坚持一个简单的模型,像

var BST = function(data) { 
    this.insert(data); 
}; 

BST.prototype.insert = function(data) { 
    if (typeof this.data == 'undefined') { 
     this.data = data; 
    } else if (data < this.data) { 
     if (!this.left) { 
      this.left = new BST(); 
     } 
     this.left.insert(data); 
    } else if (data > this.data) { 
     if (!this.right) { 
      this.right = new BST(); 
     } 
     this.right.insert(data); 
    } 
}; 

BST.prototype.inOrder = function(func) { 
    if (typeof this.data != 'undefined') { 
     this.left && this.left.inOrder(func); 
     func(this.data); 
     this.right && this.right.inOrder(func); 
    } 
}; 

注意,这完全省去了一个nullNode,因为 - 嘿! - 它是JavaScript,那么为什么不使用undefined和动态对象扩展等美妙的东西。

+0

感谢这绝对是我的代码更好的结构。 – Likhit 2012-04-18 13:21:46

1

是的,在这种情况下,您可以使用常量实例,因为所有空节点都是相同的,并且没有不同的引用(如“父”属性)。为了创造这样一个常数,你需要一个地方来存储它;这可以是一个(私人)变量或类似

BST.emptyleaf = new BST(null); 

的东西,你也可以使用Singleton模式:

function BST(data) { 
    if (data === null || data === undefined) { 
     if (BST.emptyleaf) 
      return BST.emptyleaf; // singleton instance if available 
     this.data = null; 
     this.left = null; 
     this.right = null; 
     BST.emptyleaf = this; // else create it for re-use 
    } else { 
     this.data = data; 
     this.left = new BST(null); 
     this.right = new BST(null); 
    } 
} 
相关问题