バイナリツリーのバランスが取れているかどうかを確認する最短プログラムを作成する


15

バランスの取れたバイナリツリーの各ノードでは、左の子サブツリーと右の子サブツリーの高さの最大差は最大1です。

二分木の高さは、ルートノードからルートから最も遠いノードの子までの距離です。

以下に例を示します。

           2 <-- root: Height 1
          / \
         7   5 <-- Height 2
        / \   \
       2   6   9 <-- Height 3
          / \  /
         5  11 4 <-- Height 4 

バイナリツリーの高さ:4

以下は、二分木とそれらがバランスされているかどうかに関するレポートです。

テストケース1

上記のツリーは不均衡です。

テストケース2

上記のツリーはバランス取れています。

バイナリツリーのルートを入力として受け入れ、ツリーのバランスが取れていない場合はfalsey値を返し、ツリーのバランスが取れている場合はtrue値を返す、可能な限り最短のプログラムを作成します。

入力

バイナリツリーのルート。これは、ルートオブジェクトへの参照の形式でも、バイナリツリーの有効な表現であるリストの形式でもかまいません。

出力

真理値を返します:ツリーのバランスが取れている場合

falsey値を返します。ツリーのバランスが取れていない場合。

二分木の定義

ツリーは、値と2つの他のツリーまたはそれらへのポインターを含むオブジェクトです。

バイナリツリーの構造は次のようになります。

typedef struct T
{
   struct T *l;
   struct T *r;
   int v;
}T;

バイナリツリーにリスト表現を使用する場合、次のようになります。

[root_value, left_node, right_node]

2
入力は空の木でもよいですか?
tsh

1
ツリーの最初の例では、リーフを削除する4と、残りのツリーのバランスが取れていますか?
ニール

いいえ、その例ではなく、ASCIIアートを使用した最初のものを意味しました。
ニール

私自身の実装「C、117バイト」によると:「5」から始まる右側のサブアームツリーの高さがありません、2で、左側のサブアームツリーの高さは0です
T.サリム

編集は少なくとも6文字ですが、「balanced」と「binary」の間のコンマを削除してください-「binary tree」は名詞句なので、「balanced、binary tree」と書くことは「red、snow mobile」と同等です-コンマは不要です。
ゲザケレクセニー

回答:


8

ゼリー、11バイト

ḊµŒḊ€IỊ;߀Ạ

オンラインでお試しください!

空のツリーはで表され[]ます。


この質問に最初に答えてくれたErikに感謝します。Jellyは、このサイトで非常に人気のある言語です。私はこの言語を実装するために自由を取るべきだと思います。堅牢なゴルフスクリプト言語から学ぶのに適しています。
T.サリム

Erik the Outgolferおめでとう、あなたは勝者です。
T.サリム

3

プロローグ(SWI)、49バイト

N+_/B/C:-X+B,Y+C,abs(X-Y)<2,N is max(X,Y)+1.
0+e.

オンラインでお試しください!

Value/Left_Child/Right_Child空のツリーをatom として、ツリーを表しeます。Defines +/2、成功または失敗を通じて出力し、左側にアンバインド変数(または既にツリーの高さに等しい変数)と右側にツリーがあります-height引数が受け入れられない場合、定義するために9バイトを追加します-T:-_+T.

N + _/B/C :-            % If the second argument is a tree of the form _Value/B/C,
    X+B,                % X is the height of its left child which is balanced,
    Y+C,                % Y is the height of its right child which is balanced,
    abs(X-Y) < 2,       % the absolute difference between X and Y is strictly less than 2,
    N is max(X,Y)+1.    % and N is the height of the full tree.
0 + e.                  % If, on the other hand, the second argument is e, the first is 0.

(各ノードの値を入力から省略できる場合は、_/-2バイト取り出すことができます。)
無関係な文字列


3

Python 3.8(プレリリース)133 125バイト

b=lambda t:((max(l[0],r[0])+1,abs(l[0]-r[0])<2)if(l:=b(t[1]))[1]and(r:=b(t[2]))[1]else(0,0))if t else(0,1)
h=lambda t:b(t)[1]

オンラインでお試しください!

「リスト」形式のツリーを取る:ノードがある[value, left, right]leftありright、ノードです。

関数を呼び出す h

戻り値0またはFalseアンバランスツリーの。戻り値1Trueバランスの取れたツリーの。

ゴルフをしていない:

# Returns tuple (current height, subtrees are balanced (or not))
def balanced(tree):
  if tree: # [] evaluates to False
    left = balanced(tree[1])
    right = balanced(tree[2])
    # If  the subtrees are not both balanced, nothing to do, just pass it up
    if left[1] and right[1]:
      height = max(left[0], right[0]) + 1
      subtrees_balanced = abs(left[0] - right[0]) < 2
    else:
      height = 0 # Value doesn't matter, will be ignored
      subtrees_balanced = False
  else:
    height = 0
    subtrees_balanced = True
  return (height, subtrees_balanced)

def h(tree):
  return balanced(tree)[1]

-10:取り消すための逆論理 not s

呼び出しの途中で引数を取ることが許可されている場合、これは(115バイト)に短縮できます。

(b:=lambda t:((max(l[0],r[0])+1,abs(l[0]-r[0])<2)if(l:=b(t[1]))[1]and(r:=b(t[2]))[1]else(0,0))if t else(0,1))(_)[1]

_確認するための木であること。



2

JavaScript、162バイト

f=x=>{for(f=0,s=[[x,1]];s[0];){if(!((d=(t=s.pop())[0]).a&&d.b||f))f=t[1];if(f&&t[1]-f>1)return 0;if(d.a)s.push([d.a,t[1]+1]);if(d.b)s.push([d.b,t[1]+1])}return 1}

オンラインでお試しください!

入力の形式はオブジェクトです

root={a:{node},b:{node},c:value}

説明

for(f=0,s=[[x,1]];s[0];){if(!((d=(t=s.pop())[0]).a&&d.b||f))f=t[1]

幅優先検索を実行すると、1つ以上のブランチが欠落している最初のノードの深さが検索されます。

if(f&&t[1]-f>1)return 0;if(d.a)s.push([d.a,t[1]+1]);if(d.b)s.push([d.b,t[1]+1])}

幅優先探索を継続し、いずれかの要素が分岐を欠いている最初のノードの深さより2深い場合、ゼロを返します。

return 1}

そのようなノードが見つからない場合は、1を返します


1
幅優先検索をよりうまく行う方法はおそらくありますが、私はそれを考えることができませんでした。
fəˈnɛtɪk

1
これは、葉を取り除いたときにバランスがとれる最初の例のようないくつかの有効なケースでは失敗すると思います4
ニール

1

ジュリア、56バイト

f(t)=t!=()&&(-(f.(t.c)...)^2<2 ? maximum(f,t.c)+1 : NaN)

バイナリツリーを表す次の構造体:

struct Tree
    c::NTuple{2,Union{Tree,Tuple{}}}
    v::Int
end

c 左右のノードと空のタプルを表すタプルです ()はノードが存在しないことを通知するために使用されます。

NaN偽の値は、すべての整数が真実です。


1
エンコーディングがUTF-8であると仮定すると、これはTIOの組み込みバイトカウンターによると、実際には57バイトです。とにかく、CG&CCへようこそ!
関連のない文字列

1
はい、あなたが正しい。実際に56バイトになるように修正しました
user3263164


0

C、117バイト

h(T*r){r=r?1+h(h(r->l)>h(r->r)?r->l:r->r):0;}b(T*r){return r->l&&!b(r->l)||r->r&&!b(r->r)?0:abs(h(r->l)-h(r->r))<=1;}

構造体の実装は次のとおりです。

 typedef struct T
    {
        struct T * l;

        struct T * r;

        int v;

    } T;

JDoodleでこれを試してください


これは117バイトのように見えますが、<2代わりにその最後のチェックで行うことができます
Jo King

また、これがどの程度有効かはわかりません。なぜなら、提出の外部で定義されたデータ構造に依存しているためです
Jo King

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.