【问题标题】:Function to create a binary search tree recursively递归创建二叉搜索树的函数
【发布时间】:2019-05-03 17:21:39
【问题描述】:

Picture of Question with specific details

我正在尝试编写一个创建二叉搜索树的函数。到目前为止,这是我所拥有的:

def add_items(bst, low, high):
    if low == high:
        bst.insert(high)
        return
    else:
        left = add_items(bst, low, high)
        right = add_items(bst, low, high)
        item = BinarySearchTreeMap.Item(low)
        node = BinarySearchTreeMap.BinarySearchTreeMap.Node(item)
        node.left = left
        node.right = right
        return node

我注意到的问题是函数在完成所有递归调用时返回一个节点。我想返回这个二叉搜索树的根,但我不知道最后如何返回它。图片包含对我正在尝试做的事情的更详细描述。我感谢任何人可能有的任何帮助、建议或想法。 add_items 实际上是一种辅助函数,因为它被这段小 sn-p 代码调用:

def create_complete_bst(n):
    bst = BinarySearchTreeMap.BinarySearchTreeMap()
    add_items(bst, 1, n)
    return bst

附:这是我已经提供并在这个程序中使用的二叉搜索树类

class BinarySearchTreeMap:

class Item:
    def __init__(self, key, value=None):
        self.key = key
        self.value = value


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

    def num_children(self):
        count = 0
        if (self.left is not None):
            count += 1
        if (self.right is not None):
            count += 1
        return count

    def disconnect(self):
        self.item = None
        self.parent = None
        self.left = None
        self.right = None


def __init__(self):
    self.root = None
    self.size = 0

def __len__(self):
    return self.size

def is_empty(self):
    return len(self) == 0


# raises exception if not found
def __getitem__(self, key):
    node = self.find(key)
    if (node is None):
        raise KeyError(str(key) + " not found")
    else:
        return node.item.value

# returns None if not found
def find(self, key):
    curr = self.root
    while (curr is not None):
        if (curr.item.key == key):
            return curr
        elif (curr.item.key > key):
            curr = curr.left
        else:  # (curr.item.key < key)
            curr = curr.right
    return None


# updates value if key already exists
def __setitem__(self, key, value):
    node = self.find(key)
    if (node is None):
        self.insert(key, value)
    else:
        node.item.value = value

# assumes key not in tree
def insert(self, key, value=None):
    item = BinarySearchTreeMap.Item(key, value)
    new_node = BinarySearchTreeMap.Node(item)
    if (self.is_empty()):
        self.root = new_node
        self.size = 1
    else:
        parent = self.root
        if(key < self.root.item.key):
            curr = self.root.left
        else:
            curr = self.root.right
        while (curr is not None):
            parent = curr
            if (key < curr.item.key):
                curr = curr.left
            else:
                curr = curr.right
        if (key < parent.item.key):
            parent.left = new_node
        else:
            parent.right = new_node
        new_node.parent = parent
        self.size += 1


# raises exception if key not in tree
def __delitem__(self, key):
    node = self.find(key)
    if (node is None):
        raise KeyError(str(key) + " is not found")
    else:
        self.delete_node(node)

# assumes key is in tree + returns value assosiated
def delete_node(self, node_to_delete):
    item = node_to_delete.item
    num_children = node_to_delete.num_children()

    if (node_to_delete is self.root):
        if (num_children == 0):
            self.root = None
            node_to_delete.disconnect()
            self.size -= 1

        elif (num_children == 1):
            if (self.root.left is not None):
                self.root = self.root.left
            else:
                self.root = self.root.right
            self.root.parent = None
            node_to_delete.disconnect()
            self.size -= 1

        else: #num_children == 2
            max_of_left = self.subtree_max(node_to_delete.left)
            node_to_delete.item = max_of_left.item
            self.delete_node(max_of_left)

    else:
        if (num_children == 0):
            parent = node_to_delete.parent
            if (node_to_delete is parent.left):
                parent.left = None
            else:
                parent.right = None

            node_to_delete.disconnect()
            self.size -= 1

        elif (num_children == 1):
            parent = node_to_delete.parent
            if(node_to_delete.left is not None):
                child = node_to_delete.left
            else:
                child = node_to_delete.right

            child.parent = parent
            if (node_to_delete is parent.left):
                parent.left = child
            else:
                parent.right = child

            node_to_delete.disconnect()
            self.size -= 1

        else: #num_children == 2
            max_of_left = self.subtree_max(node_to_delete.left)
            node_to_delete.item = max_of_left.item
            self.delete_node(max_of_left)

    return item

# assumes non empty subtree
def subtree_max(self, curr_root):
    node = curr_root
    while (node.right is not None):
        node = node.right
    return node


def inorder(self):
    for node in self.subtree_inorder(self.root):
        yield node

def subtree_inorder(self, curr_root):
    if(curr_root is None):
        pass
    else:
        yield from self.subtree_inorder(curr_root.left)
        yield curr_root
        yield from self.subtree_inorder(curr_root.right)

def __iter__(self):
    for node in self.inorder():
        yield node.item.key

【问题讨论】:

  • 为什么要递归地添加节点?作业不需要这个。
  • 我的印象是递归解决方案会更容易。我确实考虑过做一个迭代的解决方案,但也在这部分画了一个空白。
  • BinarySearchTreeMap 类已经有一个 insert 方法,它创建项目和节点并将其放置在树中的正确位置。你的工作就是用所有应该插入的数字作为键(可能None作为值)重复调用它。
  • 我原本打算这样做,但使用该类的 insert 方法并不能创建具有正确结构的二叉搜索树,如图所示。
  • 对于平衡树插入调用必须以正确的顺序进行:(1)检查high &lt; low并返回(这种情况可能在递归期间发生)。 low == high 的情况保持不变。 (2) 设置middle = (low + high) // 2insert它。然后让函数递归地关心low .. (middle - 1)(将创建左子树)和(middle + 1) .. high(右子树)的范围。应该够了。不需要在函数中创建节点或项目对象。

标签: python class recursion binary-search-tree


【解决方案1】:

根据建议修改后:

def create_complete_bst(n):
    bst = BinarySearchTreeMap.BinarySearchTreeMap()
    add_items(bst, 1, n)
    return bst


def add_items(bst, low, high):
    if low == high:
        bst.insert(high)
        return
    elif high < low:
        return
    else:
        mid = (low+high) // 2
        bst.insert(mid)
        add_items(bst, low, mid-1)
        add_items(bst, mid+1, high)
        return bst

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 2019-04-24
    • 2021-07-03
    相关资源
    最近更新 更多