【问题标题】:In order BST traversal: find为了 BST 遍历:find
【发布时间】:2014-06-05 03:27:20
【问题描述】:

我正在尝试查找二叉搜索树的第 k 个最小元素,但我在使用递归时遇到了问题。我了解如何打印树顺序/后序等,但我无法返回元素的等级。有人能指出我在哪里犯错吗?一般来说,我很难理解树中的递归。

编辑:这是一个练习,所以我不想使用内置函数。我有另一个解决方案,我在插入节点时跟踪左右子节点的数量,并且该代码工作正常。我想知道是否可以使用中序遍历来做到这一点,因为它似乎是一个更简单的解决方案。

class BinaryTreeNode:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


def traverseInOrder(root,order):

    if root == None:

        return
    traverseInOrder(root.left,order+1)
    print root.data,
    print order

    traverseInOrder(root.right,order)


"""
             a
           /   \
          b     c
        /  \   /  \
       d    e f    g
     /  \
    h    i
"""
h = BinaryTreeNode("h")
i = BinaryTreeNode("i")
d = BinaryTreeNode("d", h, i)
e = BinaryTreeNode("e")
f = BinaryTreeNode("f")
g = BinaryTreeNode("g")
b = BinaryTreeNode("b", d, e)
c = BinaryTreeNode("c", f, g)
a = BinaryTreeNode("a", b, c)

print traverseInOrder(a,0)

【问题讨论】:

    标签: python binary-search-tree


    【解决方案1】:

    如果这是一项学术练习,请让 traverseInOrder(或根据目的量身定制的类似方法)返回它访问过的孩子的数量。从那里开始,事情变得更简单了。

    如果这不是学术性的,请查看http://stromberg.dnsalias.org/~dstromberg/datastructures/ - 类似字典的对象都是树,并且支持迭代器 - 所以找到第 n 个是 zip(tree, range(n)) 的问题。

    【讨论】:

    • 嗨,是的,我已经在另一个练习中这样做了。我只是想知道是否可以使用中序遍历来做到这一点。我实现的另一个解决方案是在插入节点时跟踪左右子节点的数量。
    • 我想知道是否可以使用带有中序遍历的简单计数器并在计数器达到数字 k 时退出。例如,h 会返回 1,d 会返回 2,i 会返回 3 等等。所以如果我想要第三个最小的,我会在打印 i 时停止
    【解决方案2】:

    您可以先在二叉搜索树中找到 smallets 元素。然后从那个元素调用一个方法给你下一个元素 k 次。

    对于find_smallest_node 方法,请注意您可以“按顺序”遍历所有节点,直到达到最小。但是这种方法需要 O(n) 时间。

    但是,你不需要递归来找到最小节点,因为在 BST 中最小节点只是最左边的节点,所以你可以遍历节点直到找到一个没有左子节点的节点,它需要 O(log n) 时间:

    class BST(object):
    
      def find_smallest_node(self):
        if self.root == None:
          return
        walking_node = self.root
        smallest_node = self.root
        while walking_node != None:
          if walking_node.data <= smallest_node.data:
            smallest_node = walking_node
          if walking_node.left != None:
            walking_node = walking_node.left
          elif walking_node.left == None:
            walking_node = None
        return smallest_node
    
    
      def find_k_smallest(self, k):
        k_smallest_node = self.find_smallest_node()
        if k_smallest_node == None:
          return 
        else:
          k_smallest_data = k_smallest_node.data
        count = 1
        while count < k:
          k_smallest_data = self.get_next(k_smallest_data)
          count += 1
        return k_smallest_data
    
    
      def get_next (self, key):
       ... 
    

    只需要在将节点插入树时保留它们的父节点。

    class Node(object):
      def __init__(self, data, left=None, right=None, parent=None):
        self.data = data
        self.right = right
        self.left = left
        self.parent = parent
    

    具有上述方法和def get_next (self, key) 函数的bst 类的实现是here。上面的文件夹包含它的测试用例并且它工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多