当前位置: 首页 > 知识库问答 >
问题:

Prolog是树平衡的

丌官绍元
2023-03-14

如果T是一棵平衡的树,我需要实现一个谓词isBal的/1,以便isBal的(T)为真。

在这种情况下,二叉树由结构节点(左、右)定义,其中左和右可以是另一个节点或任何Prolog数据项。

我目前掌握的情况是:

height(node(L,R), Size) :-
    height(L, Left_Size),
    height(R, Right_Size),
    Size is Left_Size + Right_Size + 1 .
height(l(_),1).

isBalanced(l(_)).
isBalanced(node(B1,B2)):-
    height(B1,H1),
    height(B2,H2),
    abs(H1-H2) =< 1,
    isBalanced(B1),
    isBalanced(B2).

预期产出:

?- isBalanced(1).
true.
?- isBalanced(node(1,2)).
true.
?- isBalanced(node(1,node(1,node(1,2)))).
false.

它不起作用,任何建议将不胜感激!

共有1个答案

樊宏义
2023-03-14

你如何代表你的树?在我看来,

  • l(_)表示空树,
  • 节点(L, R)表示非空树。

我怀疑您的高度/2有一个错误,因为您似乎将空树的高度定义为1(而不是0)。

我可能会将二叉树表示如下:

> < li>nil —空树 < li>

树(D,L,R) —非空树,其中

  • D:有效载荷数据
  • L:左子树
  • R:右子树

所以那个可能代表树

    a
   / \
  b   c   
 /   / \
d   e   f

作为

tree( a ,
  tree( b ,
    tree( d , nil , nil ) ,
    nil
  ) ,
  tree( c ,
    tree( e , nil , nil ) ,
    tree( f , nil , nil ) 
) .

叶节点(没有子树的树)看起来像这样

tree( data , nil , nil )

平衡的确定

所以,从这个表示和定义开始工作

二叉树是平衡的,如果:

  • 它的左子树是平衡的
  • 它的右子树是平衡的
  • 子树各自的高度相差不超过1

我们可以很容易地为问题编写一个描述性的解决方案:

is_balanced( nil         ) .  % the empty tree is balanced
is_balanced( tree(_,L,R) ) :- % a non-empty tree is balanced IF ...
  is_balanced(L) ,            % - the left sub-tree is balanced
  is_balanced(R) ,            % - the right sub-tree is balanced
  tree_height(L,LH) ,         % - the height of the left sub-tree
  tree_height(R,RH) ,         % - the height of the right sub-tree
  abs( LH - RH ) < 2          % - differ by no more than 1
  .                           % Right?

我们只需要计算树的高度。

高度的计算

人们可以计算这样一棵树的高度如下:

tree_height( nil         , 0 ) .  % the depth of an empty tree is zero.
tree_height( tree(_,L,R) , H ) :- % for a non-empty tree...
  tree_height( L , LH ) ,         % - we compute the height of the left subtree
  tree_height( R , RH ) ,         % - we compute the height of the right subtree
  H is 1 + max( LH , RH )         % - the overall height is 1 more than the higher of the two values thus obtained.
  .                               % Right?

效率

人们可能会注意到

  • 似乎发生了很多树木穿越,并且
  • is_balanced/2tree_height/2 有可疑的相似之处。

因此,人们可以通过混合两者并动态计算深度来优化事情:

编辑:添加包装谓词is_balanced/1

is_balanced( T ) :- is_balanced( T, _ ) .

is_balanced( nil         , 0 ) .   % the empty tree is balanced and has a height of zero.
is_balanced( tree(_,L,R) , H ) :-  % a non-empty tree is balanced IF ...
  is_balanced( L , LH ) ,          % - its left subtree is balanced, and
  is_balanced( R , RH ) ,          % - its right subtree is balanced, and 
  abs( LH - RH) < 2 ,              % - their respective heights differ by no more than 1, and
  H is 1 + max( LH , RH )          % - the current tree's height is 1 more than the larger of the heights of the two subtrees.
  .                                % Easy! (And elegant!)
 类似资料:
  • 我正在解决“破解编码面试”中的以下问题:实现一个函数来检查二叉树是否平衡。平衡树是这样一种树:任何节点的两个子树的高度相差不会超过一个。 这本书的示例解决方案(复制如下)假设从节点发出的树是平衡的,如果(a)节点的左子树和右子树是平衡的;和(b)节点本身是平衡的。我在试图理解为什么会这样?以上两个条件的满足如何证明从节点发出的整个树是平衡的? 谢啦

  • 我正在解决LeetCode问题110。平衡二叉树: 给定一棵二叉树,确定它是否是高度平衡的。 对于这个问题,高度平衡的二叉树定义为: 一种二叉树,其中每个节点的左右子树的高度相差不超过1。 我已经看到了这个问题的解决方案,包括这个: 我的问题是:为什么要添加此代码? 当我从代码中删除它时,它看起来工作得很好。但是,当测试用例为< code>[1,2,2,3,null,null,3,4,null,n

  • 主要内容:二叉排序树转化为平衡二叉树,构建平衡二叉树的代码实现,总结上一节介绍如何使用二叉排序树实现动态 查找表,本节介绍另外一种实现方式—— 平衡二叉树。 平衡二叉树,又称为  AVL 树。实际上就是遵循以下两个特点的二叉树: 每棵子树中的左子树和右子树的深度差不能超过 1; 二叉树中每棵子树都要求是平衡二叉树; 其实就是在二叉树的基础上,若树中每棵子树都满足其左子树和右子树的深度差都不超过 1,则这棵二叉树就是平衡二叉树。 图 1 平衡与不平衡的二叉树及结点的

  • 我实现了下面的C代码,以检查二叉树是否平衡,即左右子树的高度相差最多1。但是,我不确定它是否有效,或者以错误的方式重复检查子树。有人能引导我吗?

  • NowCoder 题目描述 平衡二叉树左右子树高度差不超过 1。 解题思路 // java private boolean isBalanced = true; public boolean IsBalanced_Solution(TreeNode root) { height(root); return isBalanced; } private int height(Tre

  • 排序二叉树中存在一个问题就是可能会退化成一个链表,当只有左子树或者右子树有节点的时候,此时排序二叉树就像链表一样,但因为排序二叉树在插入查询的时候还要判断左右子树的问题,这样查询的效率反而变低,从而引出了平衡二叉树 平衡二叉树又称平衡搜索树(Self-balance Binary Search Tree)又称AVL树,同时保证了查询和添加的效率。首先平衡二叉树是一颗排序二叉树,且它是空树或者他的每