2012-04-17 30 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); 
    } 
} 
相關問題