一、题目:二叉树的镜像

题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。例如下图所示,左图是原二叉树,而右图则是该二叉树的镜像。

  该二叉树节点的定义如下,采用C#语言描述:

    public class BinaryTreeNode
{
public int Data { get; set; }
public BinaryTreeNode leftChild { get; set; }
public BinaryTreeNode rightChild { get; set; } public BinaryTreeNode(int data)
{
this.Data = data;
} public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right)
{
this.Data = data;
this.leftChild = left;
this.rightChild = right;
}
}

二、解题思路

2.1 核心步骤

  Step1.先序遍历原二叉树的每个节点,如果遍历到的结点有子结点,就交换它的两个子结点。

  Step2.递归遍历每个节点的子节点,同样,如果遍历到的子节点有子节点,就交换它的两个子节点。

  当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。下图展示了求二叉树的镜像的过程:

2.2 代码实现

  (1)递归版实现

    public static void SetMirrorRecursively(BinaryTreeNode root)
{
if (root == null || (root.leftChild == null && root.rightChild == null))
{
return;
} BinaryTreeNode tempNode = root.leftChild;
root.leftChild = root.rightChild;
root.rightChild = tempNode; if (root.leftChild != null)
{
// 递归调整左子树为镜像
SetMirrorRecursively(root.leftChild);
} if (root.rightChild != null)
{
// 递归调整右子树为镜像
SetMirrorRecursively(root.rightChild);
}
}

  (2)循环版实现

    public static void SetMirrorIteratively(BinaryTreeNode root)
{
if (root == null)
{
return;
} Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
stack.Push(root); while (stack.Count > )
{
BinaryTreeNode node = stack.Pop(); BinaryTreeNode temp = node.leftChild;
node.leftChild = node.rightChild;
node.rightChild = temp; if (node.leftChild != null)
{
stack.Push(node.leftChild);
} if (node.rightChild != null)
{
stack.Push(node.rightChild);
}
}
}

三、单元测试

  为了便于测试,封装了两个辅助方法,设置孩子节点和生成层次遍历的字符串:

    /// <summary>
/// 辅助方法:设置root的lChild与rChild
/// </summary>
public void SetSubTreeNode(BinaryTreeNode root, BinaryTreeNode lChild, BinaryTreeNode rChild)
{
if (root == null)
{
return;
} root.leftChild = lChild;
root.rightChild = rChild;
} /// <summary>
/// 辅助方法:生成二叉树元素的字符串用于对比
/// </summary>
public string GetNodeString(BinaryTreeNode root)
{
if (root == null)
{
return null;
} StringBuilder sbResult = new StringBuilder(); Queue<BinaryTreeNode> queueNodes = new Queue<BinaryTreeNode>();
queueNodes.Enqueue(root);
BinaryTreeNode tempNode = null;
// 利用队列先进先出的特性存储节点并输出
while (queueNodes.Count > )
{
tempNode = queueNodes.Dequeue();
sbResult.Append(tempNode.Data); if (tempNode.leftChild != null)
{
queueNodes.Enqueue(tempNode.leftChild);
} if (tempNode.rightChild != null)
{
queueNodes.Enqueue(tempNode.rightChild);
}
} return sbResult.ToString();
}

3.1 功能测试

    // 01.测试完全二叉树:除了叶子节点,其他节点都有两个子节点
// 8
// 6 10
// 5 7 9 11
[TestMethod]
public void MirrorTest1()
{
BinaryTreeNode node1 = new BinaryTreeNode();
BinaryTreeNode node2 = new BinaryTreeNode();
BinaryTreeNode node3 = new BinaryTreeNode();
BinaryTreeNode node4 = new BinaryTreeNode();
BinaryTreeNode node5 = new BinaryTreeNode();
BinaryTreeNode node6 = new BinaryTreeNode();
BinaryTreeNode node7 = new BinaryTreeNode(); SetSubTreeNode(node1, node2, node3);
SetSubTreeNode(node2, node4, node5);
SetSubTreeNode(node3, node6, node7); BinaryTreeHelper.SetMirrorIteratively(node1);
string completed = GetNodeString(node1);
Assert.AreEqual(completed,"");
} // 02.测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
// 8
// 7
// 6
// 5
//
[TestMethod]
public void MirrorTest2()
{
BinaryTreeNode node1 = new BinaryTreeNode();
BinaryTreeNode node2 = new BinaryTreeNode();
BinaryTreeNode node3 = new BinaryTreeNode();
BinaryTreeNode node4 = new BinaryTreeNode();
BinaryTreeNode node5 = new BinaryTreeNode(); node1.leftChild = node2;
node2.leftChild = node3;
node3.leftChild = node4;
node4.leftChild = node5; BinaryTreeHelper.SetMirrorIteratively(node1);
string completed = GetNodeString(node1);
Assert.AreEqual(completed, "");
} // 03.测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
// 8
// 7
// 6
// 5
// 4
[TestMethod]
public void MirrorTest3()
{
BinaryTreeNode node1 = new BinaryTreeNode();
BinaryTreeNode node2 = new BinaryTreeNode();
BinaryTreeNode node3 = new BinaryTreeNode();
BinaryTreeNode node4 = new BinaryTreeNode();
BinaryTreeNode node5 = new BinaryTreeNode(); node1.rightChild = node2;
node2.rightChild = node3;
node3.rightChild = node4;
node4.rightChild = node5; BinaryTreeHelper.SetMirrorIteratively(node1);
string completed = GetNodeString(node1);
Assert.AreEqual(completed, "");
}

3.2 特殊输入测试

    // 04.测试只有一个结点的二叉树
//
[TestMethod]
public void MirrorTest4()
{
BinaryTreeNode node1 = new BinaryTreeNode(); BinaryTreeHelper.SetMirrorIteratively(node1);
string completed = GetNodeString(node1);
Assert.AreEqual(completed, "");
} // 05.测试空二叉树:根结点为空指针
[TestMethod]
public void MirrorTest5()
{
BinaryTreeNode node1 = null;
BinaryTreeHelper.SetMirrorIteratively(node1);
string completed = GetNodeString(node1);
Assert.AreEqual(completed, null);
}

3.3 测试结果

  (1)测试通过情况

  (2)代码覆盖率

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

剑指Offer面试题:18.二叉树的镜像的更多相关文章

  1. 剑指Offer:面试题19——二叉树的镜像(java实现)

    问题描述: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树结点定义为: public class TreeNode { int val = 0; TreeNode left = null; Tr ...

  2. 剑指offer面试题19 二叉树的镜像

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像.  输入描述 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ ...

  3. 剑指Offer - 九度1521 - 二叉树的镜像

    剑指Offer - 九度1521 - 二叉树的镜像2013-11-30 23:32 题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入 ...

  4. 剑指offer——面试题18.1:删除链表中重复的节点

    // 面试题18(二):删除链表中重复的结点 // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复 // 结点被删除之后,链表如图3.4(b)所示. #include &l ...

  5. 剑指offer:对称的二叉树(镜像,递归,非递归DFS栈+BFS队列)

    1. 题目描述 /** 请实现一个函数,用来判断一颗二叉树是不是对称的. 注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的 */ 2. 递归 思路: /** 1.只要pRoot.left和 ...

  6. 剑指offer十八之二叉树的镜像

    一.题目 操作给定的二叉树,将其变换为源二叉树的镜像.二叉树的镜像定义:        源二叉树 : 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树: 8 / \ 10 6 / \ ...

  7. 剑指Offer:面试题25——二叉树中和为某一值的路径(java实现)

    问题描述: 输入一棵二叉树和一个整数,打印出二叉树中结点指的和为输入整数的所有路径.从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.二叉树结点的定义如下: public class Tree ...

  8. 剑指Offer:面试题18——树的子结构(java实现)

    问题描述: 输入两棵二叉树A和B,判断B是不是A的子结构.二叉树结点的定义如下: public class TreeNode { int val = 0; TreeNode left = null; ...

  9. [刷题] 剑指offer 面试题18:删除链表节点

    要求 给定单向链表的头指针和一个节点指针,在O(1)时间内删除该节点 常规思路:从头节点a开始顺序遍历,发现p指向要删除的节点i,然后把p的m_pNext指向i的下一个节点j,时间复杂度O(n) O( ...

  10. 剑指offer——面试题18:删除链表的节点

    #include"List.h" void DeleteNode(ListNode** pHead,ListNode* pToBeDeleted) { if(*pHead==nul ...

随机推荐

  1. 【Java EE 学习 69 中】【数据采集系统第一天】【SSH框架搭建】

    经过23天的艰苦斗争,终于搞定了数据采集系统~徐培成老师很厉害啊,明明只是用了10天就搞定的项目我却做了23天,还是模仿的...呵呵,算了,总之最后总算是完成了,现在该好好整理该项目了. 第一天的内容 ...

  2. Hadoop单机模式安装-(2)安装Ubuntu虚拟机

    网络上关于如何单机模式安装Hadoop的文章很多,按照其步骤走下来多数都失败,按照其操作弯路走过了不少但终究还是把问题都解决了,所以顺便自己详细记录下完整的安装过程. 此篇主要介绍在虚拟机设置完毕后, ...

  3. AgileEAS.NET SOA 中间件Web运行容器管理功能已全部开源,欢迎大家下载、使用、反馈

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  4. [MS SQL Server]SQL Server如何开启远程访问

    在日常工作中,经常需要连接到远程的MS SQL Server数据库中.当然也经常会出现下面的连接错误. 解决方法: 1. 设置数据库允许远程连接,数据库实例名-->右键--->属性---C ...

  5. 【leetcode】Isomorphic Strings

    题目简述: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the ...

  6. BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流

    1305: [CQOI2009]dance跳舞 Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲 ...

  7. spin.js

    $ajax提交,菊花加载的方式和位置: $.ajax({ type: "get", url: "http://www.xxx.com/test.html", b ...

  8. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

    有时候,当我们使用"mysql"."mysqladmin"."mysqldump"等命令管理数据库时,服务器抛出类似如下错误: 一.错误现场 ...

  9. supervisor-1:基础篇

    别人博客转载,做个记录 原文链接:http://lixcto.blog.51cto.com/4834175/1539136 有阵子没写博客了,这段时间一直在研究python django框架和前端相关 ...

  10. 《DSP using MATLAB》示例Example5.18