我正在尝试使用递归在python中实现二进制搜索树。我被困在程序中发生的一些无限递归中。我通过传递地址和数据对函数RecursBST进行递归调用,直到顶部遍历到它的左或右子级的None值为止。
class createnode:
def __init__(self,data):
self.root=data
self.left=None
self.right=None
class createbinarysearchtree:
def __init__(self, data = None):
self.top=None
def RecursBST(self,top,data):
if self.top is None:
self.top=createnode(data)
elif self.top.root>data:
self.top.left=self.RecursBST(self.top.left,data)
elif self.top.root<data:
self.top.right=self.RecursBST(self.top.right,data)
conv=createbinarysearchtree();
conv.RecursBST(conv.top,50)
conv.RecursBST(conv.top,40)
我运行到以下错误:
self.top.left=self.RecursBST(self.top.left,data)
RuntimeError: maximum recursion depth exceeded
看起来您在每个递归调用中都引用了同一个对象:自己。RecvesBST(self.top.left,数据)通过使用'self.top'而不是参数'top'的函数。试试这样的东西:
class createnode:
def __init__(self,data):
self.root=data
self.left=None
self.right=None
class createbinarysearchtree:
def __init__(self, data = None):
self.top=createnode(data)
def RecursBST(self,top,data):
if top is None:
return createnode(data)
if top.root is None:
top.root=data
elif top.root>data:
top.left=self.RecursBST(top.left,data)
elif top.root<data:
top.right=self.RecursBST(top.right,data)
我已经重构了您的类,使它们的名称有意义(Node和BST)。
我认为代码中的主要错误是总是引用“self”,并且总是从同一个实例调用。如果你这样做,你总是在节点上得到相同的数据,这就是为什么你的递归永远不会结束,因为它总是在同一个节点上被阻塞。我认为更容易将节点引用作为参数传递,并从中进行适当的递归调用,此外,您正在分配左变量和右变量,但从不返回任何内容。检查代码:
class Node(object):
def __init__(self, data):
self.root = data
self.left = None
self.right = None
class BST(object):
def __init__(self):
self.top = None
def recursBST(self, node, data):
if node is None:
node = Node(data)
elif self.top.root > data:
node.left = self.recursBST(node.left, data)
elif self.top.root < data:
node.right = self.recursBST(node.right, data)
return node
def insert(self, data):
self.top = self.recursBST(self.top, data)
conv = BST()
conv.insert(8)
conv.insert(3)
conv.insert(6)
conv.insert(1)
conv.insert(-1)
conv.insert(10)
conv.insert(14)
conv.insert(50)
还要记住在任何python类上添加“对象”。这是python 2.7上引入的一个特性,所以不包含它是一种不好的做法。查看此项以获取更多信息。
额外好处:您可以通过执行顺序横切来检查插入算法是否正确,之后,元素应按递增顺序打印(在本例中)。但这取决于你:)
缺少提供递归终止条件并更改递归状态的代码:
从…起https://en.wikipedia.org/wiki/Recursion_termination
在计算中,递归终止是指满足某些条件,递归算法停止调用自己并开始返回值。只有在每次递归调用时,递归算法更改其状态并向基本情况移动时才会发生这种情况。
若递归从未结束,那个么它必须运行到最大递归深度限制。
在代码中没有遇到这个问题的唯一情况是没有顶层节点,否则递归是无限的。
有一个很好的工具,你可以用它来可视化你的代码或其他答案中提供的代码:
http://www.pythontutor.com/
这样你就能对实际发生的事情有一个印象,如果这是你想要实现的。
FMc
提供的问题评论已经很好地回答了您面临的问题(引用):
通常,BST有三种方法:insert()
,delete()
,和search()
。您当前的实现通过执行与插入相关的工作(创建节点)和与搜索相关的工作来混淆事情。此外,还有一个相关的样式注释增加了这种普遍的混淆:通常类是事物或名词(BinarySearchTree或Node),而不是动作(createnode或createbinarysearchtree)。
这是作业,不要贴代码。求你了,谢谢你。 我被指派创建一个计算BST中特定的深度的方法。 为此,我需要a方法。因此,要递归地找到它,我需要创建一个助手方法。 我知道我需要在树中搜索包含我要查找的数据的节点。为此,我编写了以下代码: 然而,这是行不通的,因为每次进行递归调用时,将保持;本质上,它是在重置深度值。我不知道如何在调用之间保持的值。
从二叉查找树中删除节点时,您可以将节点替换为左侧的最大子节点或右侧的最小子节点。 我很难理解以下实现执行删除操作的方式。 上面的代码包括以下步骤: < li >查找替换节点。 < li >让替换节点引用已删除节点的左右子节点。 < li >让已删除节点的左右子节点将替换节点作为父节点。 < li >让替换节点引用已删除节点的父节点作为自己的父节点。 < li >清理。 我有困难的部分特别是递归。据
问题内容: 我知道Go有一个包含搜索功能的程序包,但这是出于教育目的。我一直在尝试在Go中实现二进制搜索算法,但无法使其正常工作。 这是我的代码: 它总是打印。为什么? 问题答案: 二进制搜索的逻辑是合理的。唯一的问题是您忘记了将每个递归调用的结果分配给和。 当前,您有以下这些递归调用: 您只需要分配结果:
问题内容: 这是我到目前为止所获得的,但是没有用: 问题答案: 这是二进制插入的快速示例:
给定二叉查找树(BST)和整数val的根。 在BST中找到该节点的值等于val的节点,并返回以该节点为根的子树。如果这样的节点不存在,则返回null。 为什么'ans=root'不起作用??
我正在尝试实现一个二叉查找树,但是“搜索”函数对于除了根之外的每个条目都返回了错误的值。 该函数应返回其值与键参数匹配的节点的地址,如果节点不存在,则返回 NULL。 当我运行代码时,我得到以下内容: 我知道每个节点的“左”和“右”指针链接正确,因为“delAll”函数成功删除了所有节点。 将“cout”语句添加到“search”函数表明该函数似乎返回了正确的地址。为什么从主主调用时会打印错误的地