编写最短程序以检查二叉树是否平衡


15

对于平衡二叉树中的每个节点,左子子树和右子子树的高度最大差值为1。

二叉树的高度是指从根节点到最远离根节点的子节点的距离。

下面是一个示例:

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

二叉树的高度:4

以下是二进制树和有关它们是否平衡的报告:

测试用例1

上面的树是不平衡的

测试案例2

上面的树是平衡的

编写尽可能短的程序,该程序接受二叉树的根作为输入,如果树不平衡,则返回假值,如果树平衡,则返回真值。

输入值

二叉树的根。这可能是以对根对象的引用或什至是二叉树的有效表示形式的列表的形式。

输出量

返回真实值:如果树是平衡的

返回falsey值:如果树为un平衡。

二叉树的定义

树是一个对象,其中包含一个值以及另外两个树或指向它们的指针。

二叉树的结构如下所示:

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'-不需要逗号。
格扎·凯雷克森伊

Answers:


8

果冻,11字节

ḊµŒḊ€IỊ;߀Ạ

在线尝试!

空树由表示[]


感谢Erik率先回答此问题。果冻无疑是该网站上非常流行的语言。我认为我应该自由地实施这种语言。可以从强大的高尔夫脚本语言中学习。
T. Salim

恭喜大公埃里克(Erik the Outgolfer),您赢了。
T. Salim

3

Prolog(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,空树为原子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.

(如果每个节点的值都可以从输入中省略,则_/可以
减去


3

Python 3.8(预发行版)133125字节

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]与节点leftright为节点。

调用功能h

退货0False表示不平衡的树。返回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:逆逻辑摆脱nots

如果允许在调用过程中接受参数,则可以将其缩短为(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]

执行广度优先搜索可以找到缺少一个或多个分支的第一个节点的深度。

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}

如果找不到这样的节点,则返回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是表示左节点和右节点的元组,空元组()用于表示不存在节点。

Falsey的值为NaN,任何整数都是true的。


1
根据TIO的内置字节计数器,假设编码为UTF-8,则实际上为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,

0

Python 2中99个 96 94字节

lambda A:A==[]or(abs(D(A[1])-D(A[2]))<2)*f(A[1])*f(A[2])
D=lambda A:A>[]and-~max(map(D,A[1:]))

在线尝试!

Jo King 3个字节。

将输入作为:空节点为[],其他节点为[<value>, <leftNode>, <rightNode>]。输出0/1为False / True。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.