问题描述
二叉树的镜像定义:
源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5
从上面的例子可以发现,得出求一个镜像二叉树的过程:先前序遍历每个节点,如果有子节点,就交换它的两个子节点。当交换完所有的非叶节点的左右子节点之后,就能得到树的镜像。
上述变化过程可以理解为:根节点8下面还有子节点,所以交换它的左右子树10和6,然后检查交换后左子节点10是否有子节点,发现有,继续交换左右子节点11和9,然后检查11是否有子节点,发现没有,返回到10,检查右子节点9有没有子节点,发现也没用,返回上一个根节点8,检查右子树6有没有子节点,发现有,以此类推,最终交换完所有非叶节点的左右子节点。
以下为测试源码:
using System;
namespace 二叉树的镜像
{
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x)
{
val = x;
}
}
class Program
{
static void Main(string[] args)
{
TreeNode tree = CreateTree(null);
Console.WriteLine("前序遍历原二叉树:");
PrintTreeByPreorder(tree);
Console.WriteLine("\n中序遍历原二叉树:");
PrintTreeByInorder(tree);
tree = Mirror(tree);
Console.WriteLine("\n前序遍历镜像二叉树:");
PrintTreeByPreorder(tree);
Console.WriteLine("\n中序遍历镜像二叉树:");
PrintTreeByInorder(tree);
}
/// <summary>
/// 创建二叉树的镜像,并返回镜像的头节点
/// </summary>
/// <param name="root">二叉树的头节点</param>
/// <returns>镜像的头节点</returns>
public static TreeNode Mirror(TreeNode root)
{
if (root == null)
return null;
TreeNode tree = root.left;
root.left = root.right;
root.right = tree;
//如果左子树还有节点,继续交换左子树的子节点
if (root.left != null)
root.left = Mirror(root.left);
//如果右子树还有节点,继续交换右子树的子节点
if (root.right != null)
root.right = Mirror(root.right);
return root;
}
/// <summary>
/// 创建二叉树
/// </summary>
/// <param name="root">二叉树的根节点</param>
/// <returns>新建二叉树的根节点</returns>
public static TreeNode CreateTree(TreeNode root)
{
TreeNode tree = new TreeNode(1);
if (root == null)
root = tree;
tree.left = new TreeNode(2);
tree.right = new TreeNode(3);
tree.left.left = new TreeNode(4);
tree.left.right = new TreeNode(5);
tree.right.left = new TreeNode(6);
tree.right.right = new TreeNode(7);
return root;
}
/// <summary>
/// 按前序序列打印二叉树
/// </summary>
/// <param name="root">二叉树根节点</param>
private static void PrintTreeByPreorder(TreeNode root)
{
if (root == null)
return;
Console.Write(root.val + "-->");
PrintTreeByPreorder(root.left);
PrintTreeByPreorder(root.right);
}
/// <summary>
/// 按中序序列打印二叉树
/// </summary>
/// <param name="root">二叉树根节点</param>
private static void PrintTreeByInorder(TreeNode root)
{
if (root == null)
return;
PrintTreeByInorder(root.left);
Console.Write(root.val + "-->");
PrintTreeByInorder(root.right);
}
}
}