欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二叉树的镜像 三种方法 详细!

程序员文章站 2024-01-29 08:46:10
...

输入一个二叉树,将它变换为它的镜像。

样例
输入树:
8
/
6 10
/ \ /
5 7 9 11

[8,6,10,5,7,9,11,null,null,null,null,null,null,null,null]
输出树:
8
/
10 6
/ \ /
11 9 7 5

[8,10,6,11,9,7,5,null,null,null,null,null,null,null,null]

思路:
1,递归遍历,然后交换,很简单看代码:

 public void mirror(TreeNode root) {
        
        if(root==null)//递归的终点
            return;
        TreeNode tempNode=root.left;
        root.left=root.right;
        root.right=tempNode;
        mirror(root.left);//递归左右子树
        mirror(root.right);

    }

2,前序遍历
用先序遍历的性质去遍历整个树。然后同时把左右子树交换
8
6 10
5 7 9 11

由于前序遍历是左根右,
就要用栈模拟树丛最左到深入

用一个栈,先把根节点push,然后交换他的两个儿子,然后把他的左节点压入,右节点压入,进入下一个步骤,
由于交换了位置现在在栈顶的是原来树的左节点,由于这个特殊性质,他就能再迭代下去,这栈顶就是新的节点,然后弹出再找他的左右儿子再交换,再压栈,一直这样下去,直到栈为空,二叉树的镜像转换完毕
最详细的解释:

  public void mirror(TreeNode tree) {
         if(tree == null)
            return;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(tree);
        while(!stack.isEmpty()){
            TreeNode  parent = stack.pop();
            TreeNode temp = parent.left;
            parent.left = parent.right;
            parent.right = temp;
            if(parent.left!=null){
                stack.push(parent.left);
            }
            if(parent.right!=null){
                stack.push(parent.right);
            }
        }
    }

用一个例子和图片更直观:
二叉树的镜像 三种方法 详细!

3,层序遍历
与前序遍历差不多,主要就是得用一种东西把每个节点的下一个节点遍历到,层序就是按顺序丛左儿子到右儿子迭代遍历

public void mirror(TreeNode tree) {
         if(tree == null)return;
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(tree);
        while(!queue.isEmpty()){
            TreeNode  parent = queue.getFirst();
            queue.poll();
            TreeNode temp = parent.left;
            parent.left = parent.right;
            parent.right = temp;
            if(parent.left!=null){
                queue.offer(parent.left);
            }
            if(parent.right!=null){
                queue.offer(parent.right);
            }
        }
    }

附加知识:

这里用一个链表实现队列,poll是弹出链表的头,offer是加入一个尾结点
如果链表满了,offer加入的点不能加入就返回false,而add会抛出异常
poll,remove区别:

remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似,

但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。