您的位置:首页 > 其它

反转二叉树(二叉树的镜像)

2017-10-14 19:30 260 查看


反转二叉树(二叉树的镜像)

    输入一个二叉树,输出其镜像。

    如下图,即交换所有节点的左右子树。



    这里提供两种思路:使用递归和不使用递归。

    使用的二叉树定义如下:

[java] view
plain copy

public class TreeNode {  

    int val = 0;  

    TreeNode left = null;  

    TreeNode right = null;  

  

    public TreeNode(int val) {  

        this.val = val;  

  

    }  

}  

    解决方法:

[java] view
plain copy

import java.util.LinkedList;  

import java.util.Scanner;  

  

/* 

 * 题目描述:输入一个二叉树,输出其镜像。 

 * */  

public class Solution {  

    Scanner scanner = new Scanner(System.in);  

      

    // 建立二叉树  

    public TreeNode createTree(TreeNode root) {  

        String val;  

        val = scanner.next(); // next方法每次取到一个间隔符前面的数据  

        if(val.equals("#")) {  

            return null;  

        }  

        root = new TreeNode(Integer.parseInt(val));//  System.out.println("输入的数据为:" + val);  

        root.left = createTree(root.left);  

        root.right = createTree(root.right);  

        return root;  

    }  

    // 得到二叉树的镜像  —— 递归的方式  

    public void Mirror(TreeNode root) {  

        if(root == null) {  

            return;  

        }  

        if((root.left == null) && (root.right == null)) {  

            return;  

        }  

        TreeNode temp = root.left;  

        root.left = root.right;  

        root.right = temp;  

        Mirror(root.left);  

        Mirror(root.right);  

    }  

     // 得到二叉树的镜像 —— 不使用递归  

    public void MirrorNotRecursive(TreeNode root) {  

        java.util.LinkedList<TreeNode> queue = new java.util.LinkedList<TreeNode>();  

        TreeNode temp = null;  

        if(root == null) {  

            return;  

        }  

        queue.add(root);  

        while(queue.size() != 0) {  

            TreeNode node = queue.removeFirst();  

            temp = node.left;  

            node.left = node.right;  

            node.right = temp;  

            if(node.right != null) {  

                queue.add(node.right);  // 入队的为原来的左孩子  

            }  

            if(node.left != null) {  

                queue.add(node.left);  

            }  

        }  

    }  

      

    // 层次遍历二叉树  

    public void levelTraverse(TreeNode root) {  

        if (root == null) {  

             return;  

        }  

         LinkedList<TreeNode> list = new LinkedList<TreeNode>();  

         list.add(root);  

         while (list.size() != 0) {  

            TreeNode node = list.removeFirst(); // list.removeFirst() 该方法LinkedList才有  

            System.out.print(node.val + " ");  

            if(node.left != null) {  

                 list.add(node.left);  // list.add()添加单个元素,如果不指定索引的话,元素将被添加到链表的最后  

            }  

            if(node.right != null) {  

                list.add(node.right);  

            }  

        }  

    }  

      

    public static void main(String[] args) {  

        Solution solution = new Solution();  

        TreeNode root = null;  

        root = solution.createTree(root);  

        System.out.println("原二叉树的层次遍历");  

        solution.levelTraverse(root);  

        solution.Mirror(root);  

        System.out.println("\n输出该二叉树的镜像");  

        solution.levelTraverse(root);  

        solution.MirrorNotRecursive(root);  

        System.out.println("\n输出该二叉树的镜像(非递归方式)");  

        solution.levelTraverse(root);  

    }  

}  

  

/* 

 * 测试数据: 

 * 1 2 3 # 4 # # 5 6 # # # 7 8 # # 9 10 # # 11 # #  (说明:其中#说明左右子树为空) 

 * 用先序遍历来建立树后,层次遍历结果为: 1 2 7 3 5 8 9 4 6 10 11 

 * 反转二叉树之后:1 7 2 9 8 5 3 11 10 6 4  

 */  

    上述程序的运行结果为:

    


    这个代码除实现反转二叉树之外,还实现了先序建立二叉树及层次遍历二叉树,可参见上述代码。关于实现反转二叉树的两种方式,思路参考见下面陈述。

    其中,递归的实现思路参考:http://zhidao.baidu.com/link?url=ohsjZowGYZokAf2wg7Q2w2UIZme_Tt1zuabVWGxFTfpzkmI0hC_BqBlhFAqsNSM3f0393lp0QEBMEp6WDTc0Na

[cpp] view
plain copy

void exchangeBTree(BTRee *root)  

{  

  BTRee *t;  

  if(root)  

     {  

         t=root->rChild;  

         root->rChild=root->lChild;  

         root->lChild=t;  

         exchangeBTree(root->lChild);  

         exchangeBTree(root->rChild);  

     }  

}  

   非递归的方式,参考自:

http://www.nowcoder.com/questionTerminal/bcffd7e8a0d4402c99773bed98690bb7?orderByHotValue=0&pos=1

    是借助栈进行操作,栈是后进先出,我实现的时候用LinkedList模拟了队列(先进先出)。这里的区别在于左孩子和右孩子谁先进去,如果要左孩子先出来,可以区分对待:栈需要右孩子先压栈,然后再左孩子;如果是队列,则左孩子入队,然后再是右孩子。

   

[cpp] view
plain copy

void NonRecursive_Exchange(TreeNode *T)  

{  

    Stack s;  

    TreeNode *p;  

    if (NULL == T)  

        return;  

    InitStack(&s);  

    Push(&s, T);  

    while (!isEmpty(&s))  

    {  

        T = Pop(&s);  

        p = T->left;  

        T->left = T->right;  

        T->right = p;  

        if (T->right )  

            Push(&s, T->right );  

        if (T->left )  

            Push(&s, T->left );  

    }  

    DestroyStack(&s);  

}  

    最后,该题目可在牛客网进行练习,提交代码:http://www.nowcoder.com/books/coding-interviews/564f4c26aa584921bc75623e48ca3011
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: