第1关:前序、中序、后序遍历
访问路径
- 前序遍历
如果二叉树为空树,则什么都不做,否则: 1)访问根结点。 2)先序遍历左子树。 3)先序遍历右子树。
其他遍历方式与此类似,也通过递归的方式实现。
- 中序遍历
如果二叉树为空树,则什么都不做,否则: 1)中序遍历左子树。 2)访问根结点。 3)中序遍历右子树。
- 后序遍历
如果二叉树为空树,则什么都不做,否则: 1)后序遍历左子树。 2)后序遍历右子树。 3)访问根结点。
编程要求
在右侧编辑器中的 Begin-End 区间补充代码,完成preorder()
、inorder()
、postorder()
函数,正确输出二叉树的前序、中序、后序遍历结果。二叉树根据后台接收的输入字符串所构建。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确的数值,只有所有数据全部计算正确才能通过测试:
测试输入:a b c d e f 预期输出:
前序遍历: a b d c e f
中序遍历: b d a e c f
后序遍历: d b e f c a
测试输入:a b c d 预期输出:
测试输入:( ( 7 + 4 ) * 9 )
预期输出:99
测试输入:( 5 + ( 6 - 3 ) )
预期输出:8
输出:9
编程要求
在右侧编辑器中的 Begin-End 区间补充代码,完成postordereval()
函数,计算并输出表达式解析树的表达式值。表达式解析树由通过input()
接收到的表达式字符串所构建。
前序遍历: a b c d
中序遍历: c b d a
后序遍历: c d b a
from binaryTree import BinaryTree '''请在Begin-End之间补充代码, 完成 preorder()、inorder()、postorder()''' # 前序遍历 def _preorder(a): preorder(a.b) def preorder(tree): if tree!=None: # 如果当前树的根结点为空,就递归结束 # ********** Begin ********** # print(tree.getRootVal(),end=" ") preorder(tree.getLeftChild()) preorder(tree.getRightChild()) # ********** End ********** # # 中序遍历和后序遍历跟前序遍历的语句是一样的,只是次序不一样 # 中序遍历 def _inorder(a): inorder(a.b) def inorder(tree): if tree != None: # ********** Begin ********** # inorder(tree.getLeftChild()) print(tree.getRootVal(),end=" ") inorder(tree.getRightChild()) # ********** End ********** # # 后序遍历 def _postorder(a): postorder(a.b) def postorder(tree): if tree != None: # ********** Begin ********** # postorder(tree.getLeftChild()) postorder(tree.getRightChild()) print(tree.getRootVal(),end=" ") # ********** End ********** #
第2关:后序遍历法重写表达式求值
后序遍历法对表达式求值
对表达式求值的过程其实也是一个后序遍历的过程。当二叉树只储存表达式的数据时,我们可以尽量模仿后序遍历的代码来改写求值函数。 在后序遍历中,我们先递归地后序遍历访问左子树和右子树,最后访问根结点。我们将访问左右子树的过程改为对左右子树求值的操作,先求左子树的值,再求右子树的值,然后再利用操作符的函数调用将它们在根结点处结合。
Python中的字典
Python 中的字典具有极快的查找速度,为了实现表达式求值算法,可构建键值分别为
'+'
,'-'
,'*'
和'/'
的字典。当我们在字典中查找一个操作符时,相应的函数功能会被取回。示例如下:import operator # operator模块包括一系列对应Python内部操作符的函数
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv} # 定义字典
print(opers['+'](4,5))
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确的数值,只有所有数据全部计算正确才能通过测试:
测试输入:( ( 7 + 4 ) * 9 )
预期输出:99
测试输入:( 5 + ( 6 - 3 ) )
预期输出:8
import operator
from parsetree import buildParseTree
'''请在Begin-End之间补充代码, 完成函数postordereval()'''
# 后序遍历法进行表达式求值
def postordereval(tree):
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv}
res1 = tree.getLeftChild() # 获取左节点值
res2 = tree.getRightChild() # 获取右节点值
if res1 and res2: # 如果左子树和右子树都成功返回值
# ********** Begin ********** #
fn = opers[tree.getRootVal()] # 获取加减乘除
return fn(postordereval(res1), postordereval(res2))
# ********** End ********** #
else:
# ********** Begin ********** #
return tree.getRootVal() # 根节点
# ********** End ********** #
pt = buildParseTree(input())
第3关:中序遍历生成全括号中缀表达式
中序遍历生成全括号中缀表达式
在中序遍历中,我们递归地中序遍历访问左子树,然后访问根结点,最后再递归地中序遍历访问右子树。中缀表达式是以左子表达式、操作符、右子表达式的顺序展示的,因此可由中序遍历的递归算法来实现。 如果我们对表达式解析树进行一个简单的中序遍历,我们将得到没有圆括号的原始表达式。我们可以修改基础的中序遍历的算法使我们复原全括号表达式。只要做如下修改:在递归访问左子树之前输出左括号,然后在访问右子树之后输出右括号。
使用'+'
实现字符串拼接
Python 里面可以直接用 '+'
来连接两个字符串。示例如下:
str_1 = 'he'
str_2 = 'llo'
str = str_1 + str_2
print(str)
输出:hello
编程要求
在右侧编辑器中的 Begin-End 区间补充代码,完成printexp()
函数,以“左根右”的顺序实现表达式解析树的中序遍历,从而输出表达式解析树对应的中缀表达式。表达式解析树由input()
输入的全括号表达式所构建。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确的数值,只有所有数据全部计算正确才能通过测试:
测试输入:( ( 7 + 4 ) * 9 )
输入说明:在创建表达式解析树时,我们使用split()
以空字符为分隔符对表达式创建单词表,所以输入的表达式字符串以空字符将各字符隔开。
预期输出:((7+4)*9)
输出说明:输出为表达式解析树的全括号中缀表达式。
测试输入:( ( 4 * ( 5 - 2 ) ) / ( 6 - 3 ) )
预期输出:((4*(5-2))/(6-3))
from parsetree import buildParseTree
'''请在Begin-End之间补充代码, 完成函数 printexp()'''
# 中序遍历法生成全括号中缀表达式
def printexp(tree):
sVal = "" # 用来存储中缀表达式字符串
if tree != None: # 如果当前树根结点不为空才进行以下操作
# ********** Begin ********** #
# 先判断左节点再给值
if tree.getLeftChild():
sVal = "("+printexp(tree.getLeftChild())
sVal += str(tree.getRootVal())
# ********** End ********** #
if tree.getRightChild():
# ********** Begin ********** #
sVal += printexp(tree.getRightChild())+")"
# ********** End ********** #
return sVal
pt = buildParseTree(input())