【问题标题】:Check is a tree in python is a Binary Search treeCheck is a tree in python is a Binary Search tree
【发布时间】:2021-05-05 21:48:46
【问题描述】:

我想编写一个函数来显示给定树是否为 BinarySearch。

这是我到目前为止写的:

class Node: 

     def _isBinary(self):
        
        L=[]

        if self.left is not None and self.right is not None:
            if self.left.data>self.data or self.right.data<self.data:
               L.append(1)
            else:
               L+=self.left._isBinary()
               L+=self.right._isBinary()
        else:

            if self.left is not None:
               if self.left.data>self.datat:
                  L.append(1)
               else:
                  self.left._isBinary()

            if self.right is not None:
               if self.right.data<self.data:
                  L.append(1)
               else:
                  self.right._isBinary()

       return L

class tree:
    
    def isBinary(self):
        if self.root is None:
            return
        else:
            return  not 1 in self.root._isBinary(self.root.data)

(我只是报告了代码中感兴趣的部分) 这段代码运行良好,但是当一个数字(大于根)在树的左侧,但它是一个较小数字的孩子时,给出了错误的答案:

     99
    /  \
   8   888
    \
     100

它应该给我 False,而不是它返回 True。我能做些什么? (如果可能,不完全更改我的原始代码?)

【问题讨论】:

  • 请更新代码的缩进。 Python 对缩进非常敏感,python 程序员也是如此。

标签: python recursion tree binary-tree


【解决方案1】:

另一种方法是只对 BST 进行中序遍历,然后检查它是否已排序。 BST的中序遍历是有序的。

def inorder(node):
    if node is None:
        return
    yield from inorder(node.left)
    yield node.data
    yield from inorder(node.right)


inorder_traversal = list(inorder(root))
print(all(i<=j for i, j in zip(inorder_traversal, inorder_traversal[1:]))) # check if sorted

由于all 的短路特性,您可以引入itertools.tee 以获得更好的性能。

inorder_traversal = inorder(root)
a, b = tee(inorder_traversal) # copy the `inorder_traversal` iterator
next(b) # discard first element
print(all(i<=j for i, j in zip(a,b))) # check if sorted

有关tee 工作原理的更多信息,您可以参考这个答案Iterate a list as pair (current, next) in Python

【讨论】:

  • 为什么这么冗长 =) if node: yield ... 不需要返回。
  • 让我们只支持这个答案,而不是指着化妆品。
  • 你可以引入 teeall 会短路,不确定与递归相比有多少好处
  • 短路而不是将迭代器完全消耗到列表中确实是一种改进。
  • @Thankyou 短路是针对tee 的解决方案,其中迭代器根本没有转换为列表,这个解决方案是在您的评论之前添加的,我在编辑时也提到过它它
【解决方案2】:

以下一些方法应该可行:

class Node:
    def is_binary_search(self, lo=None, hi=None):
        if lo is not None and lo > self.data:
            return False
        if hi is not None and hi < self.data:
            return False
        if self.left and not self.left.is_binary_search(lo=lo, hi=self.data):
            return False
        if self.right and not self.right.is_binary_search(lo=self.data, hi=hi):
            return False
        return True

您将那些已知的子树边界(lohi)传递到递归调用中。

【讨论】:

    【解决方案3】:

    您可以按顺序遍历树并检查值是否在升序。使用迭代器可以避免创建任何列表。

    def iter(self):
        if self.left:  yield from self.left.iter()
        yield self
        if self.right: yield from self.right.iter()
    
    from itertools import islice
    def isBinary(self):
        return all(a<b for a,b in zip(self.iter(),islice(self.iter(),1,None)))
    
        
         
    

    【讨论】:

    • 很好地使用islice 来避免遍历整个树。我很喜欢你的回答。
    【解决方案4】:

    我们可以编写is_binary_search,它接受一个输入树t,以及一个默认始终为Truecompare函数-

    def is_binary_search(t, compare = lambda _: True):
      if not t:
        return True
      else:
        return compare(t.data) \
           and is_binary_search(t.left, lambda l: compare(l) and l < t.data) \
           and is_binary_search(t.right, lambda r: compare(r) and r > t.data)
    

    我们创建两棵树来测试我们的功能 -

    • t1,一个无效的二叉搜索树,在您的示例问题中提供
    • t2,一个有效的二叉搜索树
    class node:
      def __init__(self, data, left = None, right = None):
        self.data = data
        self.left = left
        self.right = right
    
    t1 = \
      node(99, node(8, None, node(100)), node(888))
    
    #    99
    #   /  \
    #  8   888
    #   \
    #    100
    
    
    t2 = \
      node(99, node(8, None, node(10)), node(888))
    
    #    99
    #   /  \
    #  8   888
    #   \
    #    10
    
    print(is_binary_search(t1)) # False
    print(is_binary_search(t2)) # True
    

    我们还应该测试空树None和只有一个节点的树,每个都是有效的二叉搜索树 -

    print(is_binary_search(None)) # True
    print(is_binary_search(node(123))) # True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 2022-12-16
      • 1970-01-01
      • 2022-12-02
      • 2023-02-09
      • 2022-12-19
      • 1970-01-01
      相关资源
      最近更新 更多