算法导论第十二章:二叉查找树

**定义:**查找树是一种数据结构,它支持多种动态集合操作,如查找、插入、删除等,既可以用作字典,也可以用作优先队列。二叉查找树
二叉树的遍历:
二叉树的遍历分为前序遍历、中序遍历和后序遍历,可以采用递归的方法遍历,遍历一棵含n个节点的二叉树时间复杂度为O(n)。
中序遍历:先遍历左子树,然后遍历根节点,最后遍历右子树。
先序遍历:先遍历根节点,然后左子树,最后右子树。
后序遍历:先遍历左子树,然后右子树,最后根节点。

二叉树查找:
先从根节点开始,查找值大于节点值,则往右子树查找,小于则往左子树查找,直到找到值与查找值相等的节点,或者查询子树为空。算法时间复杂度为O(h),h为树的深度。
查找二叉树
最大值与最小值:
最大值:从根节点开始,一直遍历右子树,直到右子树为空,返回最后的节点值即为最大值。
最小值:从根节点开始,一直遍历左子树,直到左子树为空,返回最后的节点值即为最小值。
时间复杂度为O(h)。
后继: 节点x的后继为中序遍历顺序的下一个结点,如果节点的值均不相同,则后继为大于该节点的值里最小值得那个节点。如果x右子树非空,则后继为右子树最左边的节点,通过查找右子树最小值可得。如果右子树为空,如果存在后继y,则y为x最低祖先节点,且y的左儿子也是x的祖先,为了找到y,沿着x往上查找,直到某节点是其父节点的左儿子为止。时间复杂度为O(h)。
插入节点: 先按搜索的顺序向下遍历,直到最后插入合适的位置,新插入的节点没有儿子节点。时间复杂度为O(h)。
插入节点
删除节点: 删除节点取决于被删除的节点是否有儿子节点,分三种情况:
1,没有儿子节点,直接删除即可。
2,有一个儿子,将该节点删除,同时将其父节点和儿子节点连接上。
3,有左右儿子,则删除其后继,并用后继的值和附加数据替换该节点的值和附加数据。
时间复杂度:O(h)。
随机构造的二叉查找树深度为O(log(n))。
python代码:

# -*- coding: utf-8 -*-
"""
Created on Mon May 11 11:12:32 2020

@author: oym
"""

class Binarytree:
    def __init__(self,value=None,left=None,right=None,parent=None): #初始化
        self.value=value
        self.left=left
        self.right=right
        self.parent=None
        if left!=None:
            self.left.parent=self
        if right!= None:
            self.right.parent=self
            
    def preTraverse(self):  #前序遍历
        if self!=None:
            print(self.value, end= ' ')
            if self.left!=None:
                self.left.preTraverse()
            if self.right!=None:
                self.right.preTraverse()
        else:
            return
    def midTraverse(self):  #中序遍历
        if self!=None:
            if self.left!=None:
                self.left.midTraverse()
            print(self.value, end=' ')
            if self.right!=None:
                self.right.midTraverse()
        else:
            return
            
    def lastTraverse(self):  #后序遍历
        if self!=None:
            if self.left!=None:
                self.left.lastTraverse()
            if self.right!=None:
                self.right.lastTraverse()
            print(self.value, end=' ')
        else:
            return

    def search(self,value): #查找
        if self.value == value:
            return self
        elif (value<self.value and self.left!=None):
            return self.left.search(value)
        elif value>self.value and self.right!=None:
            return self.right.search(value)
        else:
            return
    
    def get_minimun(self):  #取最小值
        if self.left==None:
            return self
        else:
            return self.left.get_minimun()
        
    def get_maximun(self): #取最大值
       if self.right==None:
           return self
       else:
           return self.right.get_maximun()
           
    def find_successor(self): #寻找节点的后继
        if self.right:
            return self.right.get_minimun()
        else:
            p=self.parent
            x=self
            while p and p.right==x:
                x=p
                p=p.parent
            return p                                          
                
    def findvalue_successor(self,value): #寻找值得后继
        node = self.search(value)
        return node.find_successor()
    
    def insert_value(self,value):  #插入新值
        if self.value>value:
            if self.left:
                self.left.insert_value(value)
            else:
                new_node = Binarytree(value,parent=self)
                self.left=new_node
        else:
            if self.right:
                self.right.insert_value(value)
            else:
                new_node = Binarytree(value,parent=self)
                self.right=new_node
                
    def delete_value(self,value): #删除值
        node=self.search(value)
        self.delete_node(node)
        
    def delete_node(self,node):  #删除节点
        if node==None:
            return        
        else:
            if node.left==None and node.right==None:
                if node.parent!=None:
                    if node.parent.left==node:
                        node.parent.left=None
                    else:
                        node.parent.right=None   
                else:
                    node=None
            elif node.left!=None and node.right!=None:
                replace_node=self.find_successor()
                self.delete_node(replace_node)
                if node.parent==None:
                    self.value=replace_node.value
                    self =replace_node
                    
                elif node.parent.left==node:
                    node.parent.left=replace_node
                    replace_node.parent=node.parent
                else:
                    node.parent.right=replace_node
                    replace_node.parent=node.parent
                                      
                
            elif node.left==None and node.right:
                if node.parent!=None: 
                    if node.parent.left==node:
                        node.parent.left=node.right
                        node.right.parent=node.parent
                    else:
                        node.parent.right=node.right
                        node.right.parent=node.parent
                else:
                    node=node.right
            elif node.left!=None and node.right==None:
                if node.parent!=None:
                    if node.parent.left==node:
                        node.parent.left=node.left
                        node.left.parent=node.parent
                    else:
                        node.parent.right=node.left
                        node.left.parent=node.parent
                else:
                    node=node.left                              
            
        
root=Binarytree('D',Binarytree('B',Binarytree('A'),Binarytree('C')),Binarytree('E',right=Binarytree('G',Binarytree('F'))))
root.preTraverse()
print()
root.midTraverse()
print()
root.lastTraverse()
print()
print(root.search('A'))
print(root.search('H'))
print(root.get_maximun())
print(root.get_minimun())
print(root.findvalue_successor('F').value)
root.insert_value('H')
print(root.get_maximun().value)
root.delete_value('D')
print("-------------")
root.preTraverse()

        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值