《剑指Offer》(27)二叉树的镜像

题目:请完成一个函数,输入一棵二叉树,该函数输出它的镜像。

通过画图,我们可以很容易地发现,求解一棵二叉树的镜像,其实就是前序遍历(树根->左子树->右子树)其所有的非叶子结点,若遍历到的结点的左右子树均不为空,则交换其左右子树的位置。
对二叉树这种数据结构熟悉的读者,自然知道可以用递归的方法去遍历,也可以用循环的方法去遍历。
1.通过递归的方法

/**
public class TreeNode 
{
    int val = 0;//根结点的值
    TreeNode left = null;//左子结点
    TreeNode right = null;//右子结点
    public TreeNode(int val)
    {
        this.val = val;
    }
}
*/
public class Solution 
{
    public void Mirror(TreeNode root) 
    {
        if(root == null)
            return;
        if(root.left == null && root.right == null)//叶子节点
            return;
        //前序遍历(树根->左子树->右子树)所有的非叶子结点,交换左右子树
        TreeNode tmpNode = root.left;
        root.left = root.right;
        root.right = tmpNode;
        Mirror(root.left);
        Mirror(root.right);
    }
}

2.通过循环的方法
这里我们可以考虑通过借助两种数据结构来实现对二叉树的遍历,分别是堆栈队列
堆栈是一种后入先出(LIFO)的数据结构,只能在栈顶操作数据。Stack类继承自Vector类并实现了List接口,其中该类中的主要方法如下:
在这里插入图片描述

Java代码如下:

//循环:堆栈
     public void Mirror(TreeNode root) 
    {
         if(root == null)
             return;//如果根结点为空说明该二叉树为空
         Stack<TreeNode> stack = new Stack<TreeNode>();
         stack.push(root);//把项压入堆栈顶部
         TreeNode rootNode;
         TreeNode tmpNode;
         while(!stack.empty())//测试堆栈是否为空
         {
             rootNode = stack.pop();//查看并移除堆栈顶部的元素,并将其作为函数的返回值返回
             if(rootNode == null)
                 continue;
             if(rootNode.left == null && rootNode.right == null)
                 continue;//结束本轮循环,进行下一轮循环
             tmpNode = rootNode.left;
             rootNode.left = rootNode.right;
             rootNode.right = tmpNode;
             //堆栈后入先出
             stack.push(rootNode.right);
             stack.push(rootNode.left);
         }
    }

队列是一种先入先出(FIFO)的数据结构,只能在队列尾部添加元素,并在队列头部删除元素。Queue接口是与List接口、Set接口同一级别的接口,它们都是继承自顶层接口Collection,而我们常用的LinkedList类也实现了Queue接口。Queue接口中常用方法如下:

返回值类型方法摘要
booleanadd(E e) :将指定元素插入此队列,如果队列已满,则抛出IllegalStateException异常
Eelement() :获取但不移除此队列的头,如果队列已空,则抛出NoSuchElementException异常
Eremove() :获取并移除此队列的头,如果队列已空,则抛出NoSuchElementException异常
booleanoffer(E e) :将指定元素插入此队列,如果队列已满,则返回false
Epeek() :获取但不移除此队列的头,如果队列已空,则返回null
Epoll() :获取并移除此队列的头,如果队列已空,则返回null
booleanisEmpty() :测试此队列是否为空

Java代码如下:

//循环:队列
     public void Mirror(TreeNode root) 
    {
         if(root == null)
             return;
         Queue<TreeNode> queue = new LinkedList<TreeNode>();//多态
         queue.offer(root);//将指定元素插入队列
         TreeNode rootNode;
         TreeNode tmpNode;
         while(!queue.isEmpty())//测试队列是否为空
         {
             rootNode = queue.poll();//获取并移除队列头部的元素
             if(rootNode == null)
                 continue;
             if(rootNode.left == null && rootNode.right == null)
                 continue;
             tmpNode = rootNode.left;
             rootNode.left = rootNode.right;
             rootNode.right = tmpNode;
             //队列先入先出
             queue.offer(rootNode.left);
             queue.offer(rootNode.right);
         }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值