2012-04-17 14 views
2

私はjavascriptでバイナリ検索ツリーを表すプログラムを作成しています。私が望むのは、両方のptrs(左、右)をnullとして共通のツリーノードを作成する方法です。ここで
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)条件で定義されている)はnullノードとすべてのNULLポインタを割り当てたい:これは私が書いたコードです。しかし、すべてのヌル・ノードに対して、同じデータを表す新しいノードを作成する必要があります。 nullノードの共通インスタンスに割り当てる方法はありますか?私がnullノードを使用するだけではなく

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

を使用して
理由は、それがあるためnull.inOrder(func);を実行しようとするためleft or right = nullでノードに到達すると、inOrderメソッドを呼び出すには、それはTypeErrorを与えることthis.left並進ありますnull
これは、inOrder関数を変更することです。これは、各文の周りに多くの条件をもたらします。つまり、非常に洗練された実装ではありません。
また、オブジェクトのプロトタイプの外側にinOrderを定義して、それを引数としてツリーにすることもできますが、それはやりたくありません。

また、コードの2番目の改善点として、insertメソッドを検討してください。 null場合:私は

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

:私はとにかく各エントリを上書きする必要があるため

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

、私はの線に沿って何かをすることによって全く新しいツリーに、このノードを再割り当てしますこれは前者の実装が効率的ではないことを認識していますが、まだまだ簡潔です。そうする方法はありますか?

+0

「this」に割り当てることはできません。代わりに、親ノードを操作する必要があります。 – Bergi

答えて

1

しかし、私は新しいを作成するために抱えているすべてのヌルのノードのために同じデータを表すノード。 nullノードの共通インスタンスに割り当てる方法はありますか?

はい、これでコードが破損する可能性があります。それについて考えてみましょう。そのノードインスタンスでinsertメソッドを呼び出すとどうなりますか? ...

第2の問題点として、現在のモデルでは最適化できません。インプレースオブジェクト置換(there is in C#)のようなものはありません。

私は個人的に、単純なモデルで、これは完全にあるため、nullNodeの必要性を排除することを

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); 
    } 
}; 

ノートのようなもの固執するだろうが、あなたの現在のコードはOKだと思う - ちょっとを! - それはJavaScriptなので、なぜundefinedと動的オブジェクト拡張のようなすばらしいものを使用しないでください。

+0

これは間違いなく私のコードのより良い構造です。 – Likhit

1

はい、この場合、すべてのヌルノードが同じで、異なる参照(「親」プロパティなど)を持たないため、定数インスタンスを使用できます。そのような定数を作成するには、それを格納する場所が必要です。それは

BST.emptyleaf = new BST(null); 

のように(プライベート)変数か何かのいずれかであることができるそして、あなたはまた、シングルトンパターンを使用できます。

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); 
    } 
} 
関連する問題