删除最小二叉搜索树Python

时间:2018-07-21 12:38:51

标签: python binary-search-tree minimum

我试图从BST中删除最小节点,所以我在树中进行搜索,直到获得最小值为止(当root.leftnode为None时),然后将root.rightnode设置为根本身以继续BST。

问题是当我在执行此操作后检查树时,它不显示曾经发生的删除。

请有人指出我正确的方向,任何建议都值得赞赏。

class node():

    def __init__(self, key, data):

        self.data = data
        self.key = key
        self.leftnode = None
        self.rightnode = None
        self.count = 1


class binarysearch():

    def __init__(self):

        self.size = 0
        self.rootnode = None

    def insert(self, key, data):

        if self.rootnode is None:
            self.rootnode = node(key, data)
        else:
            self.insertnode(self.rootnode, key, data)

    def getroot(self):

        return self.rootnode

    def insertnode(self, root, key, data):

            if root.key == key:
                root.data = data

            elif key < root.key:
                if root.leftnode is None:                    
                    root.leftnode = node(key, data)
                else:
                    self.insertnode(root.leftnode, key, data)
            else:
                if root.rightnode is None:
                    root.rightnode = node(key, data)
                else:
                    self.insertnode(root.rightnode, key, data)

            root.count = 1 + self.sizenode(root.leftnode) + self.sizenode(root.rightnode)

    def inorder(self, root):

        if root is not None:

            self.inorder(root.leftnode)
            print(root.key)
            self.inorder(root.rightnode)

    def deletemin(self):

        if self.rootnode is None:
            print("No nodes exist")
        else:
            self.deleteminnode(self.rootnode.leftnode)

    def deleteminnode(self, root):

        if root.leftnode is not None:
            self.deleteminnode(root.leftnode)
        else:
            print (root.key, "deleted")
            root = root.rightnode


if __name__ == '__main__':

    a = binarysearch()
    a.insert(7,7)
    a.insert(1,1)
    a.insert(8,8)
    a.insert(3,3)
    a.insert(9,9)
    a.insert(2,2)
    a.insert(4,4)
    a.insert(11,11)
    a.insert(10,10)
    a.deletemin()
    a.getnodes()

2 个答案:

答案 0 :(得分:0)

您可以找到树中的所有节点以及该节点的路径,找到结果的最小值,然后遍历生成的路径以删除该节点:

ui <- fluidPage(
  titlePanel("Upload Slide Image"),
  sidebarLayout(
    sidebarPanel(fileInput("file1", "Choose png File", multiple = TRUE, 
  accept = c(".png")) ), # Input: Select a file ----
    mainPanel(imageOutput("myImage")) 
  )
)

server <- function(input, output, session){
  output$myImage <- renderImage({
    outfile <- tempfile(fileext = '.png')
    png(outfile, width = 400, height = 300) # Generate the PNG
    dev.off()
    list(src = outfile,contentType = 'image/png',width = 400, height = 300,
         alt = "This is alternate text")
  }, deleteFile = TRUE)
}

# Create Shiny app ----
shinyApp(ui, server)

创建:

        try:
            ambassador = user.ambassador_profile
            selected_event = get_object_or_404(Event, slug=event, organizer__slug=organizer)
            connected_events = ambassador.events.all()
            if selected_event in connected_events:
                print("You have an ambassador profile and you are connected.")
            else:
                print("You are not connected.")
        except user.DoesNotExist, user.ambassador_profile.ObjectDoesNotExist:
            print("No amb profile")

SELECT Table1.date, Table1.mo, Table1.parameterid, 
  IF(Table1.value = Table2.value, "True", "False") AS compare
FROM myTable AS Table1
LEFT JOIN myTable AS Table2 ON Table1.date = Table2.date AND Table1.mo = Table2.mo
  AND Table1.parameterid = Table2.parameterid AND Table1.rnc <> Table2.rnc

输出:

class Tree:
  def __init__(self, **kwargs):
    self.__dict__ = {i:kwargs.get(i) for i in ['val', 'left', 'right']}
  def get_nodes(self, current = []):
    yield [''.join(current), self.val] 
    yield from getattr(self.right, 'get_nodes', lambda _:[])(current+['1'])
    yield from getattr(self.left, 'get_nodes', lambda _:[])(current+['0'])
  def __iter__(self):
    yield self.val
    yield from [[], self.left][bool(self.left)]
    yield from [[], self.right][bool(self.right)]
  def _insert_back(self, _v):
    if not self.val:
      self.val = _v
    else:
      if _v < self.val:
         getattr(self.left, '_insert_back', lambda x:setattr(x, 'left', Tree(val=x)))(_v)
      else:
         getattr(self.right, '_insert_back', lambda x:setattr(x, 'right', Tree(val=x)))(_v)
  def remove(self, _path, _to_val, last=None):
     '''_to_val: if _to_val is None, then the item is removed. If not, the node value is set to _to_val'''
     if _path:
       getattr(self, ['left', 'right'][int(_path[0])]).remove(_path[1:], _to_val, last = self)
     else:
       if _to_val is None:
         last.left = None
         last.right = None
         for i in [[], self.left][bool(self.left)]:
           last._insert_back(i)
         for i in [[], self.right][bool(self.right)]:
            last._insert_back(i)
       else:
         self.val = _to_val

答案 1 :(得分:0)

您遇到的问题是root = root.rightnode仅重新绑定了局部变量root。不会更改您对该节点具有引用的其他位置(例如树中的父节点)。

要解决此问题,您需要更改递归函数的工作方式。与其期望它在上一次调用中完成所有工作,不如让它return为其父节点的左节点的值。然后,这将是节点本身,但是对于最小的节点,它将是其正确的子节点。

def deletemin(self):
    if self.rootnode is None:
        print("No nodes exist")
    else:
        self.rootnode = self.deleteminnode(self.rootnode)

def deleteminnode(self, root):
    if root.leftnode is not None:
        root.leftnode = self.deleteminnode(root.leftnode)
        return root
    else:
        return root.rightnode

关于名称的最后说明:使用root作为树中随机节点的名称有点奇怪。通常,一棵树只有一个根节点,而其他节点则没有父节点,因此不称为root。不幸的是,最常规的名称node已经用于您的节点类。通常应为类指定CapitalizedNames,以便lowercase_names可以专门引用实例和其他变量。不过,这只是惯例(并且list之类的内置类型违反了规则)。如果您使用标准名称样式,则其他人可能更容易理解您的代码,但是Python不会强制使用它们。它将允许您使用所需的任何名称。即使名称self也不是必需的,尽管如果在没有充分理由的情况下对方法的第一个参数使用了不同的东西(这是一个很好的理由的例子:类方法和元类的方法经常会使用),那将非常令人困惑。 cls作为其第一个参数的名称,因为该对象将是一个类。