【数据结构】二叉搜索树的python实现

【数据结构】二叉搜索树的python实现


二叉搜索树是以二叉树来组织的,对于一个二叉搜索树的节点,其左子树节点的元素值都不大于该节点元素值,其右子树节点的元素值都不小于该节点的元素值。
首先定义一个初始化二叉搜索树节点的类TNode,每一个节点包括节点元素值val,指向父节点的地址par,指向左子树的地址left,指向右子树的地址right。

class TNode(object):
    '''
    初始化树节点
    '''
    def __init__(self,val):
        self.val = val
        self.par = None
        self.left = None
        self.right = None

然后定义二叉搜索树的类BST,包括初始化根节点的函数__init__。

class BST(object):
    #1.初始化根节点
    def __init__(self):
        self.root = None

判断二叉搜索树是否为空的函数isEmpty。

    #2.判断二叉树是否为空    
    def isEmpty(self):
        if self.root == None:
            return True
        else:
            return False 

向二叉搜索树种插入新节点的函数add。采用递归方法,如果新节点的元素值小于当前节点的元素值,判断当前节点是否有左子树?如果没有,新的节点作为当前节点的左子树节点;如果有,继续与当前节点的左子树根节点比较。如果新节点元素大于当前节点的元素值,判断当前节点是否有右子树?如果没有,新节点作为当前节点的右子树节点;如果有,继续与当前节点的右子树根节点比较。

    #3.插入节点
    def add(self,data):
        '''
        input:data:待插入的节点数据
        '''
        #首先判断二叉树是否为空,如果为空,节点作为根节点
        if self.isEmpty():
            node = TNode(data)
            self.root = node
        else:
            #递归函数,如果节点小于父节点,且父节点没有左子节点,则作为父节点的左子节点;如果父节点有左子节点,将节点插入到左子树中。
            def insert(cur_node,data):
                if data <= cur_node.val:
                    if cur_node.left:
                        insert(cur_node.left,data)
                    else:
                        node = TNode(data)
                        cur_node.left = node
                        node.par = cur_node
                elif data >= cur_node.val:
                    if cur_node.right:
                        insert(cur_node.right,data)
                    else:
                        node = TNode(data)
                        cur_node.right = node
                        node.par = cur_node
            
            insert(self.root,data)

搜索二叉搜索树中是否有某个数值的节点的函数search,并返回第一个节点;

    #4.寻找二叉搜索树中是否有某个节点
    def search(self,cur_node,data):
        '''
        input:cur_node:需要查找最小节点子树的根节点
        '''
        #判断二叉搜索树是否为空
        if self.isEmpty():
            print('二叉搜索树为空,无法进行搜索操作!')
            return False
        else:
            def find(node,data):
                if node == None:
                    print('二叉搜索树中没有节点的值为:',data)
                    return False
                if node.val == data:
                    return node
                if data < node.val:
                    return find(node.left,data)
                if data > node.val:
                    return find(node.right,data)

            result = find(cur_node,data)
            return result

从子树中查找最小节点的函数findmin,从子树中查找最大节点的函数findmax。查找最小节点在左子树中递归,查找最大节点在右子树中递归。

    #5.查找最小节点和最大节点
    def findmin(self,cur_node):
        '''
        input:cur_node:需要查找最小节点子树的根节点
        '''
        #判断二叉搜索树是否为空
        if self.isEmpty():
            print('二叉搜索树为空,无法进行搜索操作!')
            return False
        else:
            def fm(node):
                if node.left:
                    return fm(node.left)
                else:
                    return node
            return fm(cur_node)
        
        
    def findmax(self,cur_node):
        #判断二叉搜索树是否为空
        if self.isEmpty():
            print('二叉搜索树为空,无法进行搜索操作!')
            return False
        else:
            def fm(node):
                if node.right:
                    return fm(node.right)
                else:
                    return node
            return fm(cur_node)

从某个子树中删除某个数值的节点的函数delete。分为三种情况:
(1)如果该节点是叶节点,直接删除。
(2)如果该节点只有一个子节点,该节点的父节点直接与其子节点连接
(3)如果该节点有两个子节点,将其右子树的最小数据替代此节点的数据,并删除有右子树的最小数据

    #6.删除某节点
    def delete(self,cur_node,data):
        '''
        input:cur_node:需要删除节点的树的根节点
              data:需要删除节点的元素值
        三种情况
        (1)如果该节点是叶节点,直接删除
        (2)如果该节点只有一个子节点,该节点的父节点直接与其子节点连接
        (3)如果该节点有两个子节点,将其右子树的最小数据替代此节点的数据,并删除有右子树的最小数据
        '''
        node = self.search(cur_node,data)
        
        if not node:
            print('删除操作:二叉搜索树没有节点的值为:',data,'无法执行删除操作')
            return False       
        else:
            # 如果该节点是叶节点
            if node.left == None and node.right == None:
                if node == self.root:
                    self.root = None
                    print('二叉搜索树为空!')
                elif node.par.left == node:
                    node.par.left = None
                elif node.par.right == node:
                    node.par.right = None
            # 如果该节点只有一个子节点,其父节点直接指向其子节点
            if node.left and node.right == None:
                if node == self.root:
                    self.root.val = node.left.val
                    self.root.left = node.left.left
                else:
                    node.par.left = node.left
                    node.left.par = node.par
            if node.right and node.left == None:
                if node == self.root:
                    self.root.val = node.right.val
                    self.root.right = node.right.right
                else:
                    node.par.right = node.right
                    node.right.par = node.par
            # 如果该节点有两个子节点,将其右子树的最小数据替代此节点的数据,并删除有右子树的最小数据
            if node.right and node.left:
                min_right = self.findmin(node.right)
                node.val = min_right.val
                self.delete(node.right,min_right.val)

采用递归方法先序遍历二叉搜索树的函数front_travel;采用递归方法中序遍历二叉搜索树的函数middle_travel和采用递归方法后序遍历二叉搜索树的函数back_travel。

    #7.递归先序遍历
    def front_travel(self):
        #如果二叉树为空,返回空列表
        if self.isEmpty():
            return []
        else:
            def loop(cur_node):
                tmp = []
                if cur_node:
                    tmp.append(cur_node.val)
                    tmp += loop(cur_node.left)
                    tmp += loop(cur_node.right)
                return tmp
            
            value_list = loop(self.root)
            return value_list
    
    #8.递归中序遍历
    def middle_travel(self):
        #如果二叉树为空,返回空列表
        if self.isEmpty():
            return []
        else:
            def loop(cur_node):
                tmp = []
                if cur_node:
                    tmp += loop(cur_node.left)
                    tmp.append(cur_node.val)
                    tmp += loop(cur_node.right)
                return tmp
            
            value_list = loop(self.root)
            return value_list
    
    #9.递归后序遍历
    def back_travel(self):
        #如果二叉树为空,返回空列表
        if self.isEmpty():
            return []
        else:
            def loop(cur_node):
                tmp = []
                if cur_node:
                    tmp += loop(cur_node.left)
                    tmp += loop(cur_node.right)
                    tmp.append(cur_node.val)
                return tmp
            
            value_list = loop(self.root)
            return value_list

你可能感兴趣的:(数据结构)