剑指offer系列-面试题27-二叉树的镜像(python)

博客围绕输入二叉树输出其镜像的问题展开。解题思路上,树的算法题大多可用递归实现,但效率低;循环实现则需用队列。代码实现包含递归版和循环版本。总结指出不要求效率用递归简单,追求效率则用循环加队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

题目例子如下:


5
6
7
8
9
10
11

5
6
7
8
9
10
11

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丛书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值