python中的二进制搜索树递归实现

时间:2017-05-20 20:02:04

标签: python python-2.7 python-3.x recursion data-structures

我正在尝试使用递归在python中实现二进制搜索树。我陷入了程序中发生的一些无限递归。我正在通过传递地址和数据对函数 RecursBST 进行递归调用,直到顶部遍历为无论是左或右子的无值。

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

3 个答案:

答案 0 :(得分:3)

您的代码缺失,以提供递归终止条件并更改递归的状态:

来自https://en.wikipedia.org/wiki/Recursion_termination

  

在计算中,递归终止是指当满足某些条件并且递归算法停止调用自身并开始返回值时。只有在每次递归调用时,递归算法改变其状态并移向基本案例

如果递归永远不会结束,那么必须进入最大递归深度限制。

在代码中没有遇到此问题的唯一情况是没有顶级节点,否则递归是无限的。

有一个很好的工具,您可以使用它来可视化您的代码或其他答案中提供的代码:

http://www.pythontutor.com/

这样您就可以了解实际情况以及这是否是您打算实现的目标。

这是在问题的另一个答案中运行bones.felipe提供的代码的最终结果:pythontutor-result-image

FMc对您提问题的评论已经为您所面临的问题提供了非常好的答案(引用):

  

通常,BST有三种方法:insert()delete()search()。您当前的实现通过执行与搜索相关的工作的插入相关工作(创建节点)而令人困惑。此外,还有一个相关的样式注释增加了这种一般的混淆:通常类是事物或名词(BinarySearchTree或Node)而不是动作(createnode或createbinarysearchtree)。

答案 1 :(得分:1)

我重构了你的类,以便他们的名字有意义(Node和BST)。

我认为代码中的主要错误是始终引用“self”并始终从相同的实例调用。如果你这样做,你总是在节点上获得相同的数据,这就是你的递归永远不会结束的原因,因为它总是停留在同一个节点上。我认为将Node引用作为参数传递更容易,并且从那里进行正确的递归调用,同时,您分配左右变量,但从不返回任何内容。检查代码:

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类上添加'object'。它是python 2.7中引入的一个特性,因此不包含它是一种不好的做法。请查看this以获取更多信息。

奖励:您可以通过执行有序横向来检查插入算法是否正确,之后,元素应按递增顺序打印(在本例中)。但这取决于你:)

答案 2 :(得分:0)

看起来你在每个递归调用中引用相同的对象:self.RecursBST( self.top.left ,数据)使用&#39; self.top&#39 ;而不是论据&#39; top&#39;功能。 尝试这样的事情:

 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)
相关问题