二叉排序树的实现(python)

来源:互联网 发布:档案软件 编辑:程序博客网 时间:2024/05/21 13:55

二叉排序树,又叫二叉搜索树,二叉查找树。

二叉搜索树中比较复杂的就是删除操作,我的删除操作写的最笨了,代码比较幼稚,但是对于初学者很容易看懂。看懂了之后再进行优化。因为我也是初学,网上大神的方法看不懂。。。就自己按照操作写了一个可怜,所以写的不是很好。

想验证自己写的对不对,所以又写了一个前序遍历。

class Node:    def __init__(self,data):        self.data = data        self.lchild = None        self.rchild = Noneclass BST:    def __init__(self,node_list):        self.root = None        for node in node_list:            self.insert(node)    def search(self,data):        bt = self.root        while bt:            entry = bt.data            if data < entry:                bt = bt.lchild            elif data > entry:                bt = bt.rchild            else:                return entry        return False    def insert(self,data):        bt = self.root        if not bt:            self.root = Node(data)            return        while True:            entry = bt.data            if data < entry:                if bt.lchild is None:                    bt.lchild = Node(data)                    return                bt = bt.lchild            elif data > entry:                if bt.rchild is None:                    bt.rchild = Node(data)                    return                bt = bt.rchild            else:                bt.data = data                return    def front_visit(self,root):        if root == None:            return        print(root.data)        self.front_visit(root.lchild)        self.front_visit(root.rchild)    def delete(self,data):        parent, node = None, self.root        if not node:            print("the tree is null")            return False        while node and node.data != data:            parent = node            if data < node.data:                node = node.lchild            else:                node = node.rchild            if not node:                return        if parent != None and parent.lchild == node:            if node.lchild is None and node.rchild is None:                parent.lchild = None                del node            elif node.lchild != None and node.rchild is None:                parent.lchild = node.lchild                del node            elif node.rchild != None and node.lchild is None:                parent.lchild = node.rchild                del node            elif node.rchild != None and node.lchild != None:                r = node.lchild                p = node                while r.rchild:                    p = r                    r = r.rchild                r.lchild = node.lchild                r.rchild = node.rchild                parent.lchild = r                p.rchild = None                del node        elif parent != None and parent.rchild == node:            if node.lchild is None and node.rchild is None:                parent.rchild = None            elif node.lchild != None and node.rchild is None:                parent.rchild = node.lchild            elif node.rchild != None and node.lchild is None:                parent.rchild = node.rchild            elif node.rchild != None and node.lchild != None:                r = node.lchild                p = node                while r.rchild:                    p = r                    r = r.rchild                r.lchild = node.lchild                r.rchild = node.rchild                p.rchild = None                parent.rchild = r                del node        elif parent is None:            r = node.lchild            p = node            while r.rchild:                p = r                r = r.rchild            # return r.data,node.data            r.lchild = node.lchild            r.rchild = node.rchild            p.rchild = None            self.root = r            del node

删除分四种情况,第一种是删除叶子节点,就可以直接删了。第二种是删除只有一个孩子的节点,需要将删除节点的孩子节点补到删除节点的位置就好了。第三种是删除有两个孩子的,有两种做法,一个是选择删除节点的左子树的最大值来补上,另一个是选择删除节点的右子树的最小值来补上。注意需要将最大值的父亲的右孩子置为None,或者将最小值的父亲的左孩子置为None,还要注意补上的那个节点要继承上删除节点的左右孩子和删除父节点的链接。第四种是第三种的特殊情况,就是删除的节点是root的时候,因为删除操作除了要记录删除节点的信息外,还要记录父亲节点的信息。但是root的无父亲节点,只需要取左树最大或者右树最小的值来补上,然后操作同第三种,最后要将树的root设置为替换后的节点。要不然这个树就没有root了哦。