编写最短的程序来计算二叉树的高度


18

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

下面是一个示例:

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

二叉树的高度:4

二叉树的定义

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

二叉树结构的结构如下所示:

typedef struct tree
{
  struct tree * l;

  struct tree * r;

  int v;

} tree;

挑战:

输入值

二叉树的根

输出量

代表二叉树高度的数字

假设您将二叉树的根作为输入,编写最短的程序来计算二叉树的高度并返回高度。字节数最少的程序(占空格)获胜。


4
没有指针的语言需要做什么?
乔纳森·艾伦

4
...但是然后我的树对象可以只具有一个属性,例如h。为此挑战,最好定义仅由列表组成的特定结构。
乔纳森·艾伦

11
@ T.Salim以后,请考虑先在沙箱中发布。
wizzwizz4

1
那么,有效的表示形式是否为长度为3的列表,[root_value, left_node, right_node]其中left_noderight_node也是可接受的二叉树?它在许多语言中都是微不足道的,但在其他一些语言中可能会很有趣。
乔纳森·艾伦

3
您可以编辑问题以包括什么构成有效的二进制结构吗?也许像这样的定义a tree is an object that contains a value and either two other trees or pointers to them。包含没有对象的语言的定义也将是很好的。
Jo King

Answers:


11

果冻,3 个字节

ŒḊ’

一个Monadic链接,该列表接受一个表示树:的列表[root_value, left_tree, right_tree],其中left_tree和中的每个right_tree都是相似的结构(如果需要,则为空),产生高度。

在线尝试!

怎么样?

果冻里的小事:

ŒḊ’ - Link: list, as described above
ŒḊ  - depth
  ’ - decremented (since leaves are `[value, [], []]`)

Jonathon Allen,这是您正在使用的一种有趣的语言。作为新手,您可以提供一个链接或网站推荐以指导人们如何使用Jelly?
T. Salim

4
单击标题中的链接-这是由网站主持人之一丹尼斯(Dennis)开发的一种高尔夫语言。
乔纳森·艾伦

2
我想知道代表一片叶子x而不是[x, [], []]... 会引起争议吗?
,Outgolfer的Erik

@EriktheOutgolfer为了保持问题的“指针”和“结构”性质,我认为每个节点都应具有相同的形式。
乔纳森·艾伦

10

Python 2中 35个  33字节

感谢Arnauld提出监督并节省了4。

f=lambda a:a>[]and-~max(map(f,a))

一个递归函数,它接受一个表示tree:的列表[root_value, left_tree, right_tree],其中left_tree和中的每个right_tree都是相似的结构(如果需要,则为空),该结构返回高度。

在线尝试!

请注意,[]它将返回False,但使用Python False==0


允许同一个人对同一问题给出两个不同的答案?
T. Salim

6
是的,当然,高尔夫是一种语言水平的竞赛。如果方法大不相同,即使使用相同语言的第二次输入有时也是可以接受的。
乔纳森·艾伦

@Arnauld Guess如此(我假设出于某些原因可能会出现非整数)
乔纳森·艾伦

6

Haskell,33个字节

h L=0 
h(N l r _)=1+max(h l)(h r)

使用自定义树类型data T = L | N T T Int,这是质询中给定的C结构的Haskell等效项。

在线尝试!


6

Perl 6,25个字节

{($_,{.[*;*]}...*eqv*)-2}

输入是一个三元素列表(l, r, v)。空树是空列表。

在线尝试!

说明

{                       }  # Anonymous block
    ,        ...  # Sequence constructor
  $_  # Start with input
     {.[*;*]}  # Compute next element by flattening one level
               # Sadly *[*;*] doesn't work for some reason
                *eqv*  # Until elements doesn't change
 (                   )-2  # Size of sequence minus 2

旧解决方案,30字节

{+$_&&1+max map &?BLOCK,.[^2]}

在线尝试!


这个&?BLOCK技巧很有趣,但是将块分配给$ 却要短几个字节
Jo King

@JoKing我不知道。将挑战性解决方案存储在动荡的全球环境中,$!或者$/感觉像对我构成欺骗。
nwellnhof

(ab)使用$之类的变量!和$ /是P6高尔夫的相当标准的做法。
user0721090601

6

05AB1E11 7 5 字节

Δ€`}N

-4个字节,感谢@ExpiredData
-2个字节感谢@Grimy

输入格式类似于Jelly答案:表示树的列表:[root_value, left_tree, right_tree],其中left_treeright_tree都是相似的结构(可选为空)。即[2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]]代表挑战说明中的树。

在线尝试验证更多测试用例

说明:

Δ     # Loop until the (implicit) input-list no longer changes:
  €`  #  Flatten the list one level
}N    # After the loop: push the 0-based index of the loop we just finished
      # (which is output implicitly as result)

请注意,尽管05AB1E是基于0的,但changes循环Δ使输出索引正确,因为它需要额外的迭代才能检查它是否不再更改。



@ExpiredData啊,当然..谢谢!:)
凯文·克鲁伊森


@Grimy我认为在循环外使用索引只能在旧版代码中起作用。:S谢谢!
凯文·克鲁伊森

5

JavaScript(ES6), 35  33字节

输入结构: [[left_node], [right_node], value]

f=([a,b])=>a?1+f(f(a)>f(b)?a:b):0

在线尝试!

已评论

f =                       // f is a recursive function taking
([a, b]) =>               // a node of the tree split into
                          // a[] = left child, b[] = right child (the value is ignored)
  a ?                     // if a[] is defined:
    1 +                   //   increment the final result for this branch
    f(                    //   and add:
      f(a) > f(b) ? a : b //     f(a) if f(a) > f(b) or f(b) otherwise
    )                     //
  :                       // else:
    0                     //   stop recursion and return 0

看起来您可以使用保存一个字节a&&-~
毛茸茸的

1
@Shaggy这将导致undefined进行比较
Arnauld


4

JavaScript(Node.js),32字节

f=a=>/,,/.test(a)&&f(a.flat())+1

在线尝试!

使用名称flat代替flatten或是smoosh代码高尔夫的好主意。

使用[]在树空节点,并[left, right, value]为节点。value这是一个整数。



3

Haskell,28个字节

使用以下数据定义:

data T a = (:&) a [T a]

高度为:

h(_:&x)=foldr(max.succ.h)0 x

2

方案,72字节

(define(f h)(if(null? h)0(+ 1(max(f(car(cdr h)))(f(car(cdr(cdr h))))))))

更易读的版本:

(define (f h)
   (if (null? h)
      0
      (+ 1 
         (max
             (f (car (cdr h)))
             (f (car (cdr (cdr h))))
         )
      )
   )
)

使用表单列表(数据,左,右)来表示树。例如

   1
  / \
  2  3
 /\
 4 5

is represented as: (1 (2 (4 () ()) (5 () ())) (3 () ())

(1
   (2
      (4 () ())
```   (5 () ())
   (3 () ())
)

在线尝试!


2

R,51字节

function(L){while(is.list(L<-unlist(L,F)))T=T+1;+T}

在线尝试!

  • 输入:格式为的嵌套列表:list(ROOT_ELEMENT, LEFT_TREE, RIGHT_TREE)

  • 算法:将树迭代地平展一个级别,直到它成为平面向量:迭代次数对应于最大深度。

受到@KevinCruijssen解决方案的启发


递归替代:

R,64字节

`~`=function(L,d=0)'if'(is.list(L),max(L[[2]]~d+1,L[[3]]~d+1),d)

在线尝试!

重新定义函数/运算符'~',使其能够计算存储在列表结构中的树的最大深度。

树的列表结构的格式为: list(ROOT_ELEMENT, LEFT_TREE, RIGHT_TREE)

  • -2感谢@Giuseppe

为什么要使用d=1,然后d-1最后呢?你不能从开始0吗?
朱塞佩

我也切换>~ 这里,所以测试用例更容易输入
Giuseppe

@ Giuseppe:当然...我错过了明显的🤦‍♂️
digEmAll


1

K(ngn / k),4个字节

解:

#,/\

在线尝试!

说明:

我想我可能错过了重点。

将树表示为3项列表(父节点;左子节点;右子节点),示例可以表示为

(2;
  (7;
    (,2);
    (6;
      (,5);
      (,11)
    )
  );
  (5;
    ();
    (9;
      (,4);
      ()
    )
  )
)

要么: (2;(7;(,2);(6;(,5);(,11)));(5;();(9;(,4);())))

因此,解决方案是迭代展平,并计算迭代次数:

#,/\ / the solution
   \ / iterate
 ,/  / flatten
#    / count

0

木炭,29字节

⊞θ⁰⊞υθFυ«≔⊕⊟ιθFΦι∧κλ⊞υ⊞Oκθ»Iθ

在线尝试!链接是详细版本的代码。在处理期间临时修改树。说明:

⊞θ⁰

将零推送到根节点。

⊞υθ

将根节点推送到所有节点的列表。

Fυ«

对树执行宽度优先搜索。

≔⊕⊟ιθ

获取此节点的深度。

FΦι∧κλ

循环遍历任何子节点。

⊞υ⊞Oκθ

告诉子节点其父节点的深度,然后将其推入所有节点的列表。

»Iθ

遍历所有节点后,将打印最后一个节点的深度。由于遍历是广度优先,因此这就是树的高度。


0

Stax,5 个字节

▐▌µ╡⌂

运行并调试

Stax既没有指针也没有null值,所以我将输入表示为[2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]]。也许这是一个不公平的优势,但这是我可以获得的最接近的优势。

解压,解压和注释,代码看起来像这样。

        The input starts on top of the input stack
Z       Tuck a zero underneath the top value in the stack.  Both values end up on the main stack.
D       Drop the first element from array
F       For each remaining element (the leaves) run the rest of the program
  G^    Recursively call the entire program, then increment
  T     Get maximum of the two numbers now ow the stack

运行这个


0

Kotlin,45个字节

val Tree.h:Int get()=1+maxOf(l?.h?:0,r?.h?:0)

假设定义了以下类别

class Tree(var v: Int, var l: Tree? = null, var r: Tree? = null)

在线尝试


0

朱莉娅,27个字节

f(t)=t≢()&&maximum(f,t.c)+1

使用以下表示二进制树的结构:

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

c是表示左节点和右节点的元组,空元组()用于表示不存在节点。


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.