1. 题目
请完成一个函数,输入一棵二叉树,该函数输出它的镜像。二叉树节点的定义如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
python版
class BinaryTreeNode(object):
def __init__(self, value, left, right):
self.value = value
self.left = left
self.right = right
题目例子如下:
2. 解题思路
我觉得,树方面的算法题大多都能使用递归来实现,只不过递归的效率比较低而已。那么本题应该也可是使用递归来实现。
既然我们已经想要用递归来实现,那么就很简单了,定义一个函数
输入:一个节点
交换节点的左右子节点
递归下去,要注意递归的基线条件
使用循环来解决的时候,我就发现用指针来实现是不可能的,因为一个指针下面对应两个子节点,这个指针指向左子节点,就无法再指向右子节点了。因此使用队列来实现循环。当然根据加入队列的顺序不同能够实现不同的效果,不过本题加入队列的顺序并不影响结果。
3. 代码实现
3.1 递归版
def mirror_recursively1(root):
"""
递归实现,前序遍历
"""
if root == None:
return
# 交换当前节点的左右子节点
root.left, root.right = root.right, root.left
# 交换左子节点的左右子节点
mirror_recursively1(root.left)
# 交换右子节点的左右子节点
mirror_recursively1(root.right)
3.2 循环版本
def mirror_recursively2(root):
"""
循环版,使用队列
"""
queue = []
if root == None:
return
queue.append(root)
# 如何前序遍历整个树,使用队列
while queue:
node = queue.pop(0) # 时间复杂度O(n), 从队列中取出第一个元素
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
node.left, node.right = node.right, node.left
#return root
# 前序遍历,根左右
def pre_order(root):
if root == None:
return
time.sleep(0.5)
print(root.value)
pre_order(root.left)
pre_order(root.right)
class Node(object):
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
if __name__ == '__main__':
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node7 = Node(7)
node8 = Node(8)
node9 = Node(9)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right = node5
node3.left = node6
node3.right = node7
node5.left = node8
node6.right = node9
print("镜像前")
pre_order(node1)
print("="*100)
#mirror_recursively1(node1)
mirror_recursively2(node1)
print("镜像后")
pre_order(node1)
4. 总结
关于树的算法,不要求效率的话直接用递归是最简单的,若要效率高一些就要使用循环+队列。
5. 参考文献
[1] 剑指offer丛书