[英]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.