二叉树的镜像(剑指OFFER 面试题27)

问题描述

二叉树的镜像定义:
源二叉树
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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33575542/article/details/80755481