二进制searchtree,尝试实现删除节点方法,指针有问题

时间:2016-06-28 16:54:30

标签: python pointers binary-search-tree nodes

我在stackoverflow找到另一个好的线程,将它链接到removing a node from a binary search tree using recursion。这是我从中获取代码的地方,它看起来像这样:

import random
from time import time

class BinaryNode:

    def __init__(self, value = None):
        """Create binary node"""
        self.value = value
        self.left = None
        self.right = None

    def add(self, val):
        """Adds a new node to the tree containing this value"""
        if val <= self.value:
            if self.left:
                self.left.add(val)
            else:
                self.left = BinaryNode(val)
        else:
            if self.right:
                self.right.add(val)
            else:
                self.right = BinaryNode(val)

    def delete(self):
        """
         Remove value of self from BinaryTree. Works in conjunction with remove
         method in BinaryTree
        """

        if self.left == self.right == None:
            return None
        if self.left == None:
            return self.right
        if self.right == None:
            return self.left

        child = self.left
        grandchild = child.right
        if grandchild:
            while grandchild.right:
                child = grandchild
                grandchild = child.right
            self.value = grandchild.value
            child.right = grandchild.left
        else:
            self.left = child.left
            self.value = child.value

        return self

class BinaryTree:

    def __init__(self):
        """Create empty binary tree"""
        self.root = None

    def add(self, value):
        """Insert value into proper location in Binary Tree"""
        if self.root is None:
            self.root = BinaryNode(value)
        else:
            self.root.add(value)

    def contains(self, target):
        """Check whether BST contains target value"""

        node = self.root
        while node:
            if target == node.value:
                return True
            if target < node.value:
                node = node.left
            else:
                node = node.right

        return False

    def remove(self, value):
        """Remove value from tree"""

        if self.root:
            self.root = self.removeFromParent(self.root, value)

    def removeFromParent(self, parent, value):
        """remove value from tree rooted at parent"""
        if parent is None:
            return None

        if value == parent.value:
            return parent.delete()
        elif value < parent.value:
            parent.left = self.removeFromParent(parent.left, value)
        else:
            parent.right = self.removeFromParent(parent.right, value)

        return parent

如果我们专注于delete类下的BinaryNode方法,我需要一些帮助来理解指针,我之前已经将我自己的二进制搜索树放在一起,但我无法理解,是{{1}一个指针?什么是self.left(见self.left.right),这是一个从“开始”的指针,很快就是根,到孩子,然后到右边(到孙子)。对我来说,grandchild方法不需要删除哪个值的参数,我觉得有点奇怪,我在其他任何地方都看不到使用该方法......

1 个答案:

答案 0 :(得分:1)

属性是对象。实际上,它们被实现为对象引用,a.k.a。指针。

self.left.right是 self (你的临时“root”)的左右孙子。 **自我*最多可以有四个grandchlidren;这是第二个(从左到右计数),左孩子的右孩子。

删除确实有一个参数: self 。这就是它如何知道要删除的节点。该方法未在别处使用,因为其他方法都不需要删除节点。你正在开发一个从外面使用的类,而不是一个自给自足的应用程序。

这能够很好地回答你目前的困惑吗?尝试用铅笔绘制树 - 并完成方法。在单步执行代码时擦除和重绘指针。也许更好,使用两种颜色,因此你有“之前”和“之后”指针,并在你进行时对这些变化进行编号。

我不会说 self 充当前哨节点; “哨兵”概念更多的是停止特定点的迭代。

至于指针/对象二分法,我怀疑你遇到麻烦的原因之一是Python不会让你经常分开这两者。每个变量值都是对变量对象的引用。

具体来说,self.right.left最终是孙子的引用。但是,Python运行时系统使用它来直接访问孙子对象。换句话说,无法真正区分它们。无论如何都要想到它;在适合您的目的时进行更改(例如抓住字段,就像它是一个对象一样,然后重置,就好像它是一个指针)。 Python使这成为一种量子态:波和粒子。

免责声明: 最终会使用熟悉的星号传递参数,以获取指向某些内容的指针,例如* my_list。在这种情况下,你有明显的区别......但Python会将波函数折回到粒子ASAP。现在不要担心,只要知道它会在晚些时候出现,所以你不要对你在那一点上学到的东西失去信心。