繁体   English   中英

Check is a tree in python 是一个Binary Search tree

[英]Check is a tree in python is a Binary Search tree

我想写一个 function 来显示给定的树是否为 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。 我能做什么? (如果可能的话,不完全改变我的原始代码?)

另一种方法是只对 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

遵循以下思路的一些方法应该有效:

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 )传递给递归调用。

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

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)))

    
     

假设一个节点是这样定义的

class Node:
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.right = right
        self.left = left

这个简单的递归 function 应该足够了。 将左右子树的两个不同比较器函数作为可调用参数传递给内部递归 function。这不是最短的解决方案,但看起来不像黑魔法(希望如此)。

def is_bst(root):
    def is_bst_recursive(node, in_order):
        if node is None:
            return True
        if not in_order(node.value):
            return False
        if node.left and node.left.value >= node.value:
            return False
        if node.right and node.right.value <= node.value:
            return False
        return (is_bst_recursive(node.left, in_order)
                and is_bst_recursive(node.right, in_order))

    return (is_bst_recursive(root.left, lambda x: x < root.value)
            and is_bst_recursive(root.right, lambda x: x > root.value))

我们可以编写is_binary_search ,它接受一个输入树t和一个默认为Truecompare function -

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)

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

  • 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM