简体   繁体   English

使用父指针在二叉查找树中删除

[英]Deletion in binary search tree with parent pointers

I have been trying to solve an on-line challenge for 9 days now. 我一直试图解决9天的在线挑战。 I have an on-line insertion deletion with repetitions of 100,000 and I need to find the median of those. 我有一个在线插入删除重复100,000,我需要找到这些的中位数。 I tried two heaps but to realise random deletion doest work. 我尝试了两个堆,但实现随机删除doest工作。 I am now on to Binary Search trees since they seem to insert and delete 100,000 data in 2 seconds on my computer. 我现在使用二进制搜索树,因为它们似乎在我的计算机上在2秒内插入和删除了100,000个数据。 I am working on python and I need to run in 16 seconds. 我正在使用python,我需要在16秒内运行。

I have checked for solutions on-line but which exactly dont cater to my need. 我已经在网上检查了解决方案,但这完全不符合我的需要。 I figured out calculating the median while inserting and deletion could be a good strategy. 我想出计算中位数,而插入和删除可能是一个很好的策略。 This I wrote two methods which get the in order successor or predecessor of a node. 我写了两个方法来获取节点的后继或前任。

The problem is as I figured it out to be is - improper assignment of parent pointers during recursive deletion. 问题是因为我认为是 - 在递归删除期间不正确地分配父指针。

I tried two techniques, both of which didn't work well, I would appreciate if I get some help! 我尝试了两种技术,这两种技术都不能很好地工作,如果我得到一些帮助,我将不胜感激!

The code: 编码:

import sys
class BSTNode:
    def __init__(self,x,parent):
        self.data = x
        self.left = None
        self.right = None
        self.count = 1
        self.parent = parent

def delete(x,T):
    if T is None:
        print('Element Not Found')
    elif x<T.data:
        T.left = delete(x,T.left)
    elif x>T.data:
        T.right = delete(x,T.right)
    elif T.left and T.right:
        TempNode = findMin(T.right)
        T.data = TempNode.data
        T.right = delete(TempNode.data,T.right)
    else:
        if T.left is None:
            T = T.right
        elif T.right is None:
            T = T.left
    return T

def findMin(T):
    if T.left:
        return findMin(T.left)
    else:
        return T

def insert(x,T,parent=None):
    if T is None:
        T = BSTNode(x,parent)
    elif x<T.data:
        T.left = insert(x,T.left,T)
    elif x>T.data:
        T.right = insert(x,T.right,T)
    else:
        T.count = T.count + 1
    return T

def inorder(T):
    if T is None:
        return
    else:
        inorder(T.left)
        b = back(T)
        if b:
            print("back:",b.data)
        print(T.data)
        n = next(T)
        if n:
            print("next:",n.data)
        inorder(T.right)

def preorder(T,i=0):
    if T is None:
        return
    else:
        for j in range(i):
            sys.stdout.write("    ")
        print(T.data)
        preorder(T.left,i+1)
        preorder(T.right,i+1)

def next(node):
    if node is None:
        return
    if node.right:
        n = node.right
        while n.left:
            n = n.left
        return n
    else:
        n = node
        while n.parent and n.parent.right is n:
            n = n.parent
        if n.parent and n.parent.left is n:
            return n.parent
        else:
            return

def back(node):
    if node is None:
        return
    if node.left:
        n = node.left
        while n.right:
            n = n.right
        return n
    else:
        n = node
        while n.parent and n.parent.left is n:
            n = n.parent
        if n.parent and n.parent.right is n:
            return n.parent
        else:
            return

T = None
T = insert(7,T)
T = insert(4,T)
T = insert(2,T)
T = insert(1,T)

T = insert(13,T)
T = insert(15,T)
T = insert(16,T)
T = insert(6,T)

T = insert(5,T)
T = insert(3,T)
T = insert(11,T)
T = insert(14,T)

T = insert(12,T)
T = insert(9,T)
T = insert(8,T)
T = insert(10,T)

T = delete(11,T)
T = delete(12,T)
T = delete(13,T)
T = delete(8,T)
preorder(T)
inorder(T)

output 产量

7
    4
        2
            1
            3
        6
            5
    14
        9
            10
        15
            16
1
('next:', 2)
('back:', 1)
2
('next:', 3)
('back:', 2)
3
('next:', 4)
('back:', 3)
4
('next:', 5)
('back:', 4)
5
('next:', 6)
('back:', 5)
6
('next:', 7)
('back:', 6)
7
('next:', 9)
9
('next:', 10)
('back:', 9)
10
('next:', 12)
('back:', 10)
14
('next:', 15)
('back:', 14)
15
('next:', 16)
('back:', 15)
16

expected - back of 9 is 7 预计 - 9回到7

my answer 我的答案

def delete(x,T,parent=None):
    if T is None:
        print('Element Not Found')
    elif x<T.data:
        T.left = delete(x,T.left,T)
    elif x>T.data:
        T.right = delete(x,T.right,T)
    elif T.count==1:
        # 2 CHILDREN
        if T.left and T.right:
            TempNode = findMin(T.right)
            T.data = TempNode.data
            T.right = delete(TempNode.data,T.right,T)
        # 0 CHILDREN
        elif T.left is None and T.right is None:
            T = None
        # 1 CHILDREN
        elif T.right is not None:
            T = T.right
            T.parent = parent
        elif T.left is not None:
            T = T.left
            T.parent = parent
    else:
        T.count = T.count - 1
    return T

now 现在

9
    4
        2
            1
            3
        5
    14
        10
        15
            16
1 (2) 
('next:', 2)
('back:', 1)
2 (4) 
('next:', 3)
('back:', 2)
3 (2) 
('next:', 4)
('back:', 3)
4 (9) 
('next:', 5)
('back:', 4)
5 (4) 
('next:', 9)
('back:', 5)
9  
('next:', 10)
('back:', 9)
10 (14) 
('next:', 14)
('back:', 10)
14 (9) 
('next:', 15)
('back:', 14)
15 (14) 
('next:', 16)
('back:', 15)
16 (15)

You don't seem to be updating the parent pointers of T after T = T.right and T = T.left in the else: part of the delete(x,T): routine. delete(x,T):例程的else:部分中, T = T.rightT = T.left之后,您似乎没有更新T的父指针。 Another option might be to update the parent pointers whenever you replace a left or right child. 另一种选择可能是在替换左或右子项时更新父指针。 I think following either of the two conventions consistently throughout the code must solve your problem. 我认为在整个代码中遵循两个约定中的任何一个必须解决您的问题。

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

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