python实现基本的二叉树结构以及生成表达式树

该篇代码的实现用到了上一篇中定义的栈,和前一篇的目的一样。如果有错误的地方或更好的办法,请不吝赐教,感谢感谢!

树节点的定义:

class tree_Node(object): # 树节点类
    def __init__(self,elem):
        self.elem = elem
        self.left = None
        self.right = None

树的定义:

class tree(object):
    def __init__(self,root):
        root = tree_Node(root)
        self.root = root
    
    def put_tree2right(self , tree_temp): # 将tree_temp 树变为 调用树的右孩子
        if isinstance(tree_temp , tree):#如果tree_temp 是树类型
            self.root.right = tree_temp.root
        else:
            print("error , this element is a unknown type, please check the expression.")
    
    def put_tree2left(self , tree_temp):# 将tree_temp 树变为 调用树的左孩子
        if isinstance(tree_temp , tree): # 如果tree_temp 是树类型
            self.root.left = tree_temp.root
        else:
            print("error , this element is a unknown type, please check the expression.")
    
    def insert_left(self,data): # 为了方便,直接插入到最左端
        newNode = tree_Node(data)
        temp = self.root
        while temp.left is not None:
            temp = temp.left
        temp.left = newNode
    
    def insert_right(self,data): # 为了方便,直接插入到最右边
        newNode = tree_Node(data)
        temp = self.root
        while temp.right is not None:
            temp = temp.right
        temp.right = newNode
        
    def pre(self,root_temp):
        if root_temp is None:
            return
        print(root_temp.elem)
        self.pre(root_temp.left)
        self.pre(root_temp.right)
    
    def preShow(self): # 先序遍历
        print(" ========= pre show ========== ")
        self.pre(self.root)
    
    def back(self , root_temp):
        if root_temp is None:
            return
        self.back(root_temp.left)
        self.back(root_temp.right)
        print(root_temp.elem)
    
    def backShow(self):# 后序遍历
        print(" ========= back show ========== ")
        self.back(self.root)
    
    def mid(self , root_temp):
        if root_temp is None:
            return
        self.mid(root_temp.left)
        print(root_temp.elem)
        self.mid(root_temp.right)
    
    def change_root_value(self , value):
        self.root.elem = value
        
    def midShow(self): # 中序遍历
        print(" =========== mid show =================== ")
        self.mid(self.root)

测试:

if __name__ == "__main__":
    tr = tree(19)
    tr.insert_right(13)
    tr.insert_right(133)
    tr.insert_right(14)
    tr.insert_left(10)
    tr.insert_left(12)
    tr.preShow()
    tr.backShow()
    tr.midShow()

测试结果如下:


算术表达式树的构造:

其输入是一个后缀表达式,如果想使用常用的中缀表达式,可以参考我python系列的上一篇文章,里面用python实现了中缀表达式转换成后缀表达式。算法基本描述如下:

假设构造a+b+c+d的表达式树:

其后缀表达式为ab+c+d+(依次遍历此序列)

  1、a压入栈中

a

 

 

 

 

 

  2、b压入栈中

a

b

 

 

 

 

  3、读到 + 时,则将栈中的前两个弹出,新建棵树tree_temp1,+作为根节点,第一个弹出的作为右孩子节点,第二弹出的作为左孩子节点,然后将tree_temp1压入栈中

tree_temp1

 

 

 

 

 

4、c压入栈中

tree_temp1

c

 

 

 

 

5、读到+时,则将栈中的前两个弹出,新建棵树tree_temp2,+作为根节点,第一个弹出的作为右孩子节点,第二弹出的作为左孩子节点,然后将tree_temp2压入栈中

tree_temp2

 

 

 

 

  

6、d压入栈中

tree_temp2

c

 

 

 

 

7、读到+时,则将栈中的前两个弹出,新建棵树tree_temp3,+作为根节点,第一个弹出的作为右孩子节点,第二弹出的作为左孩子节点,然后将tree_temp3压入栈中

tree_temp3

 

 

 

 

  

8、已经遍历完整个字符串,返回tree_temp3(为所求表达式树)

 

 

代码实现:

'''
注意:将一棵树连接成另一个点的左子树时,不能将该点的左指针指向这棵树,而是指向这这棵树的根节点。
'''

def judge_cal(string_temp):#判断当前所读的字符是否是运算符
    if string_temp in ('+' , '-' , '*' , '/'):
        return True
    return False

def pruduce_express_tree(express_list):
    stack_temp = Stack(100) # 用于临时存储
    
    for str_temp in express_list:
        
        if judge_cal(str_temp) is True:# 如果当前字符为运算符
            
            tree_temp = tree(str_temp) # 新建一个临时的树
            
            if stack_temp.empty() is True: # 判断堆栈是否为空
                print("first stack element error,please check your expression(code 1)")
                return 
            
            right_node = stack_temp.getTop() #将栈顶元素赋给右孩子节点
            stack_temp.pop() # 弹出
            
            if stack_temp.empty() is True:#
                print("second stack element error,please check your expression(code 2)")
                return
            
            left_node = stack_temp.getTop()
            stack_temp.pop()
            
            if isinstance(right_node , str): # 如果弹出的是字符串类型,则用正常的方式插入即可
                tree_temp.insert_right(right_node)
            else: # 反之,将从栈弹出的树的树根作为新树的右孩子
                tree_temp.put_tree2right(right_node)
            
            if isinstance(left_node , str): # 左孩子与右孩子类似
                tree_temp.insert_left(left_node)
            else:
                tree_temp.put_tree2left(left_node)
            
            stack_temp.push(tree_temp)
            
        else:
            stack_temp.push(str_temp)
    
    return stack_temp.getTop()

测试:

if __name__ == "__main__":
    express_list = ['a' , 'b' , '+' ,'c' , 'd' , 'e', '+' , '*' , '*']
    print(express_list)
    tree_temp = pruduce_express_tree(express_list)
    print("============================= ",type(tree_temp))
    tree_temp.preShow()
    tree_temp.backShow()
    tree_temp.midShow()
    
    example_list = ['1' , '12' , '+' , '10' , '2' , '4' , '+' , '*' , '*']
    tree_temp = pruduce_express_tree(example_list)
    tree_temp.midShow()

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值