繁体   English   中英

尝试使用递归辅助函数-Python从二进制搜索树中删除节点

[英]Trying to delete nodes from Binary Search Tree with a recursive helper function-Python

我不确定为什么我的程序不能正常工作,我想我已经解决了所有情况,但是什么也没有删除,当我打印树时有些事情在移动。 我相信我的插入函数的所有功能都可以正常工作,因为我对此没有任何问题,但是我无法成功删除。 这是两个功能:

def insert (self, x):
    def recurse (p):
        if x<p.data:
            if p.left==None:
                p.left = BSTNode (x)
            else:
                recurse (p.left)
        else:
            if p.right==None:
                p.right = BSTNode (x)
            else:
                recurse (p.right)
    # body of insert method
    if self.root==None:
        self.root = BSTNode(x)
    else:
        recurse (self.root)

这是插入,现在是删除:

def remove (self, x):
    def recurse(p,x):
        if x is p.data:
            #if p is a leaf node then prune node p from tree
            if p.left is None and p.right is None:
                del p
            # if p has a left child but no right child
            elif p.left is not None and p.right is None:
                p = p.left
                #have to move up p.left now
            #if p has a right child but no left child
            elif p.right is not None and p.left is None:
                p = p.right
                #have to move up p.right now
            #if p has a right child and a left child
            elif p.right is not None and p.left is not None:
                q = p
                while True:
                    if q.data > p.data:
                        p.data = q.data
                        break
                    else:
                        if q.right is not None:
                            q = q.right
                        elif q.left is not None:
                            q = q.left
                        else:
                            q = p
                            break
                if q is p:
                    while True:
                        if q.data > p.data:
                            p.data = q.data
                            break
                        else:
                            if q.left is not None:
                                q = q.left
                                if q.right is not None and q.right.data > p.data:
                                    q = q.right
                                    p.data = q.data
                                    break
                            elif q.right is not None:
                                q = q.right
                recurse(q,q.data)

        elif x < p.data:
            recurse(p.left,x)
        elif x > p.data:
            recurse(p.right,x)

    if self.root is None:
        print('there are no values left')
    else:
        recurse(self.root,x)

我可能使问题复杂化了,但是x这是我要删除的元素。 如果p有2个子节点,则p是self.root树,q是删除后将替换p的节点。 q是按顺序遍历下一个选择的。 我必须为我的任务使用递归帮助器函数。

这是我递归节点删除的解决方案。 它似乎正常工作:

(请在此处找到我完整的RBTree来源和测试)

class BlackNone(object):
    '''
    Represents None but with False is_red attribute.
    Introduced to fix 'p.nodes[dir].is_red' problems with None node
    '''

    # ...

L, R = 0, 1 # Left & right directions
BNone = BlackNone() # None with False is_red attribute

class RBTree(object):
    '''
    My attempt to implement Red Black Tree.
    Implementation follows this great tutorial:
    http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
    '''

    # ...

# RBTree methods:
def remove_recursive(self, root, data, done):
    if not root:
        done.append(False)
    else:
        if root.data == data:
            if BNone in root.nodes:
                save = root.nodes[not root.nodes[L]]

                # case 0:
                if root.is_red:
                    done.append(True)
                elif save.is_red:
                    save.is_red = False
                    done.append(True)

                root = BNone # actual node deletion

                return save
            else:
                heir = root.nodes[L]

                while heir.nodes[R]:
                    heir = heir.nodes[R]

                root.data = heir.data
                data = heir.data

        dir = root.data < data
        root.nodes[dir] = self.remove_recursive(root.nodes[dir],
                                                            data, done)
        if not done:
            root = self.remove_balance(root, dir, done)

    return root

def remove(self, data):
    done = []
    self.root = self.remove_recursive(self.root, data, done)
    if self.root:
        self.root.is_red = False

    return done.pop()

def remove_balance(self, root, dir, done):
    p = root
    s = root.nodes[not dir]

    if s and (not s.is_red):
        # Black sibling cases
        if (not s.nodes[L].is_red) and (not s.nodes[R].is_red):
            if p.is_red:
                done.append(True)
            p.is_red = True
            s.is_red = True
        else:
            save = root.is_red;

            p = self.rot_1(p, dir) if s.nodes[not dir].is_red else (
                                                    self.rot_2(p, dir))
            p.is_red = save
            p.nodes[L].is_red = False
            p.nodes[R].is_red = False
            done.append(True)
    elif s and s.nodes[dir]:
        # Red sibling cases
        r = s.nodes[dir]

        if (not r.nodes[L].is_red) and (not r.nodes[R].is_red):
            p = self.rot_1(p, dir)
            p.nodes[dir].nodes[not dir].is_red = True
        else:
            if r.nodes[dir].is_red:
                s.nodes[dir] = self.rot_1(r, not dir)
            p = self.rot_2(p, dir)
            s.nodes[dir].is_red = False
            p.nodes[not dir].is_red = True

        p.is_red = False
        p.nodes[dir].is_red = False
        done.append(True)

    return p

class RBNode(object):
    '''
    Red Black tree's node
    '''

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM