二叉树的镜像

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

分析:
先前序遍历这棵树的每个节点,如果遍历到的节点有子节点,就交换它的两个子节点。
当交换完的所有非叶节点的左右子节点之后,就得到树的镜像
有三种方法解决该问题
1,递归,
2,前序非递归,
3,层序非递归,
首先声明二叉树,
递归方法,根节点不为空,交换左子树和右子树,递归将子树的节点也进行交换。
前序非递归,前序遍历的非递归 根左右,
只要某节点有左子节点,就不断压入栈中,直到没有左子节点时弹出,
接着将根节点指向右子树,重复上述过程,
层序非递归,层序遍历广度优先搜索,需要用到队列,现将根节点入列,然后弹出根节点将根节点的子节点入列,不断重复,直到队列为空
将同一层的节点都进行交换
首先将根节点放入队列中,队列不为空,拿出一个节点//非叶子节点的前提下,交换左右子节点,当左子节点不为空时,将左子节点放入队列,右子节点同理。

package com.helan.d;

import sun.reflect.generics.tree.Tree;

import java.util.LinkedList;

public class MirrorOfBinaryTree {
    public static  class TreeNode{
        int val;
        TreeNode rightTree;
        TreeNode leftTree;

        public TreeNode(int val) {
            this.val = val;
        }
        public TreeNode(){}
    }
    public static void mirrorRec(TreeNode root){
        if(root==null){
            return ;
        }
        TreeNode tem=root.leftTree;
        root.leftTree=root.rightTree;
        root.rightTree=tem;
        mirrorRec(root.leftTree);
        mirrorRec(root.rightTree);
    }
    //创建二叉树结点
    public static TreeNode createBinaryTreeNode(int val){
        TreeNode root=new TreeNode();
        root.val=val;
        root.rightTree=null;
        root.leftTree=null;
        return root;

    }
    //连接二叉树结点
    public static  void connectTreeNodes(TreeNode pParents, TreeNode pLeft,TreeNode pRight){
        if(pParents!=null){
            pParents.leftTree=pLeft;
            pParents.rightTree=pRight;
        }
    }
    public static void printTreeNode(TreeNode treeNode){
        if(treeNode!=null){
            System.out.println("节点的值为:"+treeNode.val);
            if (treeNode.leftTree!=null){
                System.out.println("节点左子的值为:"+treeNode.leftTree.val);
            }else {
                System.out.println("节点左子为空!");
            }
            if (treeNode.rightTree!=null){
                System.out.println("节点右子的值为:"+treeNode.rightTree.val);
            }else {
                System.out.println("节点右子为空!");
            }
        }
    }

    private void mirrorIterPre(TreeNode root) {
        //前序非递归
        LinkedList<TreeNode> stack=new LinkedList<>();
        while (root!=null||!stack.isEmpty()){
            while(root!=null){
                stack.push(root);
                if(root.rightTree!=null||root.leftTree!=null){
                    TreeNode tem=root.leftTree;
                    root.leftTree=root.rightTree;
                    root.rightTree=tem;
                }
                root=root.leftTree;
            }
            if(!stack.isEmpty()){
                root=stack.pop();
                root=root.rightTree;
            }
        }
    }

    private void mirrorIterLevel(TreeNode root) {
        if(root==null){
            return;
        }
        LinkedList<TreeNode> queue=new LinkedList<>();
        queue.offer(root);//先进先出
        while(!queue.isEmpty()){
            TreeNode node=queue.poll();
            if(node.rightTree!=null||node.leftTree!=null){
                TreeNode tem=node.leftTree;
                node.leftTree=node.rightTree;
                node.rightTree=tem;
            }
            if(node.leftTree!=null){
                queue.offer(node.leftTree);
            }
            if(node.rightTree!=null){
                queue.offer(node.rightTree);
            }

        }
    }
    public static void printTree(TreeNode pRoot){
        printTreeNode(pRoot);
        if(pRoot!=null){
            if(pRoot.leftTree!=null){
                printTree(pRoot.leftTree);
            }
            if(pRoot.rightTree!=null){
                printTree(pRoot.rightTree);
            }
        }
    }
    // ====================测试代码====================
// 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
//            8
//        6      10
//       5 7    9  11
    void test1(){

        TreeNode pNode8 = createBinaryTreeNode(8);
        TreeNode pNode6 = createBinaryTreeNode(6);
        TreeNode pNode10 = createBinaryTreeNode(10);
        TreeNode pNode5 = createBinaryTreeNode(5);
        TreeNode pNode7 = createBinaryTreeNode(7);
        TreeNode pNode9 = createBinaryTreeNode(9);
        TreeNode pNode11 = createBinaryTreeNode(11);

        connectTreeNodes(pNode8, pNode6, pNode10);
        connectTreeNodes(pNode6, pNode5, pNode7);
        connectTreeNodes(pNode10, pNode9, pNode11);

        printTree(pNode8);//打印原始树

//        System.out.print("=====Test1: 递归镜像=====\n");
//        mirrorRec(pNode8);
//        printTree(pNode8);//打印镜像树
//
//        System.out.print("=====Test1: 前序镜像=====\n");
//        mirrorIterPre(pNode8);
//        printTree(pNode8);
        System.out.print("=====Test1: 层序镜像=====\n");
        mirrorIterLevel(pNode8);
        printTree(pNode8);


    }

    // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
//            8
//          7
//        6
//      5
//    4
    public void test2(){
        System.out.print("=====Test2 starts:=====\n");
        TreeNode pNode8 = createBinaryTreeNode(8);
        TreeNode pNode7 = createBinaryTreeNode(7);
        TreeNode pNode6 = createBinaryTreeNode(6);
        TreeNode pNode5 = createBinaryTreeNode(5);
        TreeNode pNode4 = createBinaryTreeNode(4);

        connectTreeNodes(pNode8, pNode7, null);
        connectTreeNodes(pNode7, pNode6, null);
        connectTreeNodes(pNode6, pNode5, null);
        connectTreeNodes(pNode5, pNode4, null);

        printTree(pNode8);

//        System.out.print("=====Test2: 递归镜像=====\n");
//        mirrorRec(pNode8);
//        printTree(pNode8);

//        System.out.println("前序遍历的镜像");
//        mirrorIterPre(pNode8);
//        printTree(pNode8);//打印镜像树

        System.out.print("=====Test1: 层序镜像=====\n");
        mirrorIterLevel(pNode8);
        printTree(pNode8);

    }

    // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
//            8
//             7
//              6
//               5
//                4
    public void test3(){
        System.out.print("=====Test3 starts:=====\n");
        TreeNode pNode8 = createBinaryTreeNode(8);
        TreeNode pNode7 = createBinaryTreeNode(7);
        TreeNode pNode6 = createBinaryTreeNode(6);
        TreeNode pNode5 = createBinaryTreeNode(5);
        TreeNode pNode4 = createBinaryTreeNode(4);

        connectTreeNodes(pNode8, null, pNode7);
        connectTreeNodes(pNode7, null, pNode6);
        connectTreeNodes(pNode6, null, pNode5);
        connectTreeNodes(pNode5, null, pNode4);

        printTree(pNode8);
//        System.out.print("=====Test3: 递归镜像=====\n");
//        mirrorRec(pNode8);
//        printTree(pNode8);

//        System.out.println("前序遍历的镜像");
//        mirrorIterPre(pNode8);
//        printTree(pNode8);//打印镜像树

        System.out.print("=====Test3: 层序镜像=====\n");
        mirrorIterLevel(pNode8);
        printTree(pNode8);


    }

    // 测试空二叉树:根结点为空指针
    public void test4(){
        System.out.print("=====Test4 starts:=====\n");
        TreeNode pNode = null;

        printTree(pNode);


//        System.out.print("=====Test4: 递归镜像=====\n");
//        mirrorRec(pNode);
//        printTree(pNode);

//        System.out.println("前序遍历的镜像");
//        mirrorIterPre(pNode);
//        printTree(pNode);//打印镜像树

        System.out.print("=====Test1: 层序镜像=====\n");
        mirrorIterLevel(pNode);
        printTree(pNode);

    }

    // 测试只有一个结点的二叉树
    public void test5(){
        System.out.print("=====Test5 starts:=====\n");
        TreeNode pNode8 = createBinaryTreeNode(8);

        printTree(pNode8);
//        System.out.print("=====Test5: 递归镜像=====\n");
//        mirrorRec(pNode8);
//        printTree(pNode8);

//        System.out.print("=====Test5: 前序镜像=====\n");
//        System.out.println("前序遍历的镜像");
//        mirrorIterPre(pNode8);
//        printTree(pNode8);//打

        System.out.print("=====Test1: 层序镜像=====\n");
        mirrorIterLevel(pNode8);
        printTree(pNode8);
    }

    public static void  main(String args[]){
        new MirrorOfBinaryTree().test1();
        new MirrorOfBinaryTree().test2();
        new MirrorOfBinaryTree().test3();
        new MirrorOfBinaryTree().test4();
        new MirrorOfBinaryTree().test5();

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值