blog

アルゴリズムの復習:バイナリ探索木(BST)とその検証

まず定義を見てください:二項探索木とは,空木か,次の性質を持つ二項木です:左の部分木が空木でない場合,左の部分木のすべてのノードの値はルートノードの値より小さい;右の部分木が空木でない場合,右の部分木...

Jul 22, 2020 · 3 min. read
シェア

、DFSとBFSを別々に研究しました。この節では、特殊なバイナリ木構造である バイナリ探索木を引き続き研究します。

バイナリサーチ・ツリー

左の部分木が空でない場合、左の部分木のすべてのノードの値は、そのルートノードの値よりも小さいです右の部分木が空でない場合、右の部分木のすべてのノードの値は、そのルートノードの値よりも大きいです



ここでサブツリーという概念を強調します:Tを根付き木、aをTの頂点とします。 **aとa **のすべての子孫から派生する部分グラフを有向木Tのサブツリーと呼びます。具体的には、サブツリーとは、有向木のノードの1つと、それ以下のすべてのノードから構成される木のことです。



例えば、以下はバイナリー・サーチツリーです:

以下のどちらでもありません:

<1>グラフの4ノードの位置の値は、ルートノードより大きくなければなりません。

<2>グラフの3ノードの位置の値は、ルートノードより大きくなければなりません。



バイナリ探索木の検証方法を教えてください。質問を見てください。

トピックは以下の本で分析されています。

2進木が与えられたとき、それが有効な2進探索木かどうかを判定します。

例1.

 :
 5
 / \
 1 4
 / \
 3 6
 : false
 :  : [5,1,4,null,null,3,6] 
 ルート・ノードの値は5だが、その右の子の値は4である。

例2.

 :
 5
 / \
 1 4
 / \
 3 6
 : false
 :  : [5,1,4,null,null,3,6] 
 ルート・ノードの値は5だが、その右の子の値は4である。

<节点值,右节点值>节点值>まず、設問を読んだ後、木全体を走査し、すべてのノードを比較し、左のノードの値を渡すことを思い浮かべるのは簡単ですそこでここでは、ノードに発生する最大値と最小値を保持するために、上界と下界を導入します。

再帰的な解法

トピックが明確になれば、再帰を使った解法は簡単です。ここで強調しておきたいのは、各再帰において、左ノードと右ノードのチェックサムに加え、上界と下界の判定も必要だということです。この再帰は解析が難しいので、最初にコードを示します:

func isValidBST(root *TreeNode) bool {
 if root == nil{
 return true
 }
 return isBST(root,math.MinInt64,math.MaxInt64)
}
func isBST(root *TreeNode,min, max int) bool{
 if root == nil{
 return true
 }
 if min >= root.Val || max <= root.Val{
 return false
 }
 return isBST(root.Left,min,root.Val) && isBST(root.Right,root.Val,max)
}

走行結果

もし上記の記事の再帰があまりにわかりにくければ、以下の図で理解することができます:

私が書いたすべての解答と各問題の完全な図解をeBookにまとめました。

Read next

TypeScript学習日記 - データ型

tsの環境としては、nodeを使用し、tsをグローバルにインストールすれば十分です。 しかし、どの型もneverのサブタイプではなく、never型に割り当てることもできません。 objectは、非原始型、すなわち、数値、文字列、ブーリアン、シンボル、n...以外の型を示します。

Jul 22, 2020 · 5 min read