Python二叉树的构建、解析与遍历

一、二叉树的构建有两种方法:
1.列表之列表 2.节点与引用(使用递归)
①列表之列表:使用Python特有的列表结构,用嵌套的形式进而实现,每个父节点默认有两个子节点,可以为空

def BinaryTree(r):
    return [r,[],[]]
    
def insertLeft(root,newBranch):
    t=root.pop(1)
    if len(t)>1:
        root.insert(1,[newBranch,t,[]])
    else:
        root.insert(1,[newBranch,[],[]])
    
def insertRight(root,newBranch):
    t=root.pop(2)
    if len(t)>1:
        root.insert(2,[newBranch,t,[]])
    else:
        root.insert(2,[newBranch,[],[]])

def getRootVal(root):
    return root[0]

def getRootVal(root):
    return root[0]
    
def setRootVal(root,newVal):
    root[0]=newVal

def getLeftChild(root):
    return root[1]

def getRightChild(root):
    return root[2]

a=BinaryTree(3)
insertLeft(a,5)
insertLeft(a,4)
insertRight(a,9)
l=getLeftChild(a)
setRootVal(l,'a')
print(a)

②节点与引用:运用递归的思想,所有二叉树的子树也是二叉树

class BinaryTree():
    def __init__(self,rootObj):
        self.key=rootObj
        self.leftChild=None
        self.rightChild=None

    def InsertLeft(self,newObj):
        if self.leftChild:
            t=BinaryTree(newObj)
            t.leftChild=self.leftChild #注意和后面一行的顺序
            self.leftChild=t
        else:
            self.leftChild=BinaryTree(newObj)
            
    def InsertRight(self,newObj):
        if self.rightChild:
            t=BinaryTree(newObj)
            t.rightChild=self.rightChild #注意和后面一行的顺序
            self.rightChild=t
        else:
            self.rightChild=BinaryTree(newObj)

    def getLeftChild(self):
        return self.leftChild

    def getRightChild(self):
        return self.rightChild
        
    def setRootVal(self,obj):
        self.key=obj

    def getRootVal(self):
        return self.key

r=BinaryTree('a')
print(r.getRootVal())
r.InsertLeft('a')
print(r.getLeftChild()) 
print(r.getLeftChild().getRootVal())            
r.getLeftChild().setRootVal('b')
print(r.getLeftChild().getRootVal())

二、二叉树的解析和计算
①解析
原理:使用完全括号法构建二叉树
1.遇到(,就为当前节点添加一个左节点,并下沉到该子节点;
2.遇到符号,就将当前节点的值设为当前标记的运算符,并添加一个右节点,并下沉;
3.遇到数字,就将当前节点的值设为这个数,然后返回至父节点;
4.遇到),就返回父节点

from pythonds.trees import BinaryTree
from pythonds.basic import Stack

def buildParseTree(fpexp):
    fplist=fpexp.split()
    pStack=Stack()
    eTree=BinaryTree('')
    pStack.push(eTree)
    currentTree=eTree
    for i in fplist:
        if i=='(':
            currentTree.insertLeft('')
            pStack.push(currentTree)
            currentTree=currentTree.getLeftChild()
        elif i in ['+','-','*','/']:
            currentTree.setRootVal(i)
            currentTree.insertRight('')
            pStack.push(currentTree)
            currentTree=currentTree.getRightChild()
        elif i not in ['+','-','*','/',')']:
            currentTree.setRootVal(int(i))
            parent=pStack.pop()
            currentTree=parent
        else:
            currentTree=pStack.pop()
    return eTree   
            
pt = buildParseTree("( ( 10 + 5 ) * 3 )")
print(pt.getLeftChild().getRootVal())

②计算(一般单独作为外部函数,也可以放到类里面)

import operator
def evaluate(parseTree): 
    opers={'+':operator.add,'-':operator.sub,'*':operator.mul,
           '/':operator.truediv}
    leftC=parseTree.getLeftChild()
    rightC=parseTree.getRightChild()
    
    if leftC and rightC: #带节点的子树
        fn=opers[parseTree.getRootVal()]       
        return fn(evaluate(leftC),evaluate(rightC)) #递归调用
    else: #没有子节点的节点
        return parseTree.getRootVal()
    
pt = buildParseTree("( ( 10 + 5 ) * 3 )")
print(evaluate(pt))

三、二叉树的遍历
①前序遍历:

def preorder(Tree):
    if Tree:
        print(Tree.getRootVal())
        preorder(Tree.getLeftChild())
        preorder(Tree.getRightChild())
        
pt = buildParseTree("( ( 10 + 5 ) * 3 )")
preorder(pt)

②后序遍历:(不知道书中为什么给的是左-右-根)

def postorder(Tree):
    if Tree:
        postorder(Tree.getLeftChild())
        postorder(Tree.getRightChild())
        print(Tree.getRootVal())

pt = buildParseTree("( ( 10 + 5 ) * 3 )")
postorder(pt) 

③中序遍历

def inorder(Tree):
    if Tree:
        inorder(Tree.getLeftChild())
        print(Tree.getRootVal())
        inorder(Tree.getRightChild())
    
pt = buildParseTree("( ( 10 + 5 ) * 3 )")
print(inorder(pt))

④用括号展示二叉树

def printexp(Tree):
    sVal=''
    if Tree:
        sVal='('+printexp(Tree.getLeftChild())
        sVal=sVal+str(Tree.getRootVal())
        sVal=sVal+printexp(Tree.getRightChild())+')'
    return sVal
    
pt = buildParseTree("( ( 10 + 5 ) * 3 )")
print(printexp(pt))

在这里插入图片描述前序

在这里插入图片描述
中序
在这里插入图片描述
后序(但书中的仿佛是左-右-根)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值