树结构参考链接:https://blog.csdn.net/Tonywu2018/article/details/89480282
题解参考:
https://labuladong.gitbook.io/algo/shu-ju-jie-gou-xi-lie/shou-ba-shou-shua-er-cha-shu-xun-lian-di-gui-si-wei/er-cha-shu-xi-lie-1
翻转一棵二叉树。
示例:
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/invert-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
写题之前,先明确树的几个基本概念。
class TreeNode(object):
def __init__(self, data=0, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BinTree(object):
def __init__(self):
self.root = None
self.ls = []
def add(self, data):
node = TreeNode(data)
if self.root is None:
self.root = node
self.ls.append(self.root)
return
treenode = self.ls[0]
if treenode.left is None:
treenode.left = node
self.ls.append(node)
elif treenode.right is None:
treenode.right = node
self.ls.append(node)
self.ls.pop(0)
def preOrderTraversal(self, root):
# 前序遍历(根左右):递归实现
if root is None: # 递归结束条件,根节点为None,返回
return
print(root.data) # 先中,则先打印根节点的数据项
self.preOrederTraversal(root.left) # 对左子树递归调用前序遍历函数
self.preOrederTraversal(root.right) # 对右子树递归调用前序遍历函数
def inOrderTraversal(self, root):
# 中序遍历(左根右):递归实现
if root is None: # 递归结束条件,相同
return
self.inOrderTraversal(root.left) # 先左,则先对左子树递归调用中序遍历函数
print(root.data) # 打印根节点的数据项
self.inOrderTraversal(root.right) # 最后,对右子树递归调用中序遍历函数
def postOrderTraversal(self, root):
# 后序遍历(左右根):递归实现
if root is None: # 不多说,递归结束条件
return
self.postOrderTraversal(root.left) # 先左,则先对左子树递归调用后序遍历函数
self.postOrderTraversal(root.right) # 再右,对右子树递归调用后序遍历函数
print(root.data) # 关键,最后再打印根节点的数据项
根据题解提示:
(换到Python上,有关于类的思想还没有转变过来)
# 上边写的树
from Tree import TreeNode
from Tree import BinTree
class Solution(object):
def invertTree(self, Btree: BinTree):
# 这里传进的参数对象有问题,应该传入的是树的根节点,而不是BinTree这个类
if Btree.root is None:
return
Btree.root.left, Btree.root.right = Btree.root.right, Btree.root.left
self.invertTree(Btree.root.left)
self.invertTree(Btree.root.right)
if __name__ == '__main__':
L = [4, 2, 7, 1, 3, 6, 9]
bintree = BinTree()
for i in L:
bintree.add(i)
#solution = Solution()
#solution.invertTree(bintree)
bintree.preOrderTraversal(bintree.root)
更改后的代码
class Solution(object):
def invertTree(self, root: TreeNode):
# 这里root的类型是TreeNode
if root is None:
return
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
if __name__ == '__main__':
L = [4, 2, 7, 1, 3, 6, 9]
bintree = BinTree()
for i in L:
bintree.add(i)
solution = Solution()
solution.invertTree(bintree.root) # 传入二叉树的根节点
bintree.preOrderTraversal(bintree.root)
没有理解类的定义,传入了一个类,导致了递归调用的时候,参数传入错误。
这里的类相当于一个自己定义的函数类型,里面有方法,数据等。你将这个类型的数据传入另一个函数中,并进行相关操作(面向对象的思想),就是直接改变了这个数据。(改变了root)
Q:但是参考题解说到,前后序遍历可以,中序遍历不行,为什么?
这里的不行,不是说不能翻转,而是只能部分翻转,因为,别理论了,直接上代码跑再来说明
from Tree import TreeNode
from Tree import BinTree
class Solution(object):
def invertTree(self, root: TreeNode):
if root is None:
return
self.invertTree(root.left)
root.left, root.right = root.right, root.left
self.invertTree(root.right)
if __name__ == '__main__':
L = [4, 2, 7, 1, 3, 6, 9]
bintree = BinTree()
for i in L:
bintree.add(i)
solution = Solution()
solution.invertTree(bintree.root)
bintree.preOrderTraversal(bintree.root)
翻转前 4213769(前序遍历)
得到结果4769213(前序遍历)
这是因为中序遍历交换节点的时候,
4
/ \
2 7
/ \ / \
1 3 6 9
第一次交换
4
/ \
2 7
/ \ / \
3 1 6 9
第二次交换
4
/ \
7 2
/ \ / \
6 9 3 1
神奇的事情发送了,7那边就根本不会变了,因为左边已经遍历过,现在变右边
第三次交换
4
/ \
7 2
/ \ / \
6 9 1 3
这样,右边的2的子节点变了两次,所以,对于4来说,导致只变换子节点2 7,不变换孙子节点