二叉树基础(一)

11 篇文章 0 订阅

二叉树理论基础篇

一、二叉树的种类

在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树。

1、满二叉树

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。

如图所示:

image-20220527194323696

这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个节点的二叉树。

2、完全二叉树

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。

image-20220527194639078

3、二叉搜索树

前面介绍的树,都没有数值的,而二叉搜索树是有数值的了,二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

image-20220527194746294

4、平衡二叉搜索树

平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

image-20220527194811110

二、二叉树的存储方式

二叉树可以链式存储,也可以顺序存储。

image-20220527194855375

链式存储是大家很熟悉的一种方式,那么我们来看看如何顺序存储呢?

其实就是用数组来存储二叉树,顺序存储的方式如图:

image-20220527194912565

三、二叉树的遍历方式

二叉树主要有两种遍历方式:

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走。
  2. 广度优先遍历:一层一层的去遍历。

这两种遍历是图论中最基本的两种遍历方式,后面在介绍图论的时候 还会介绍到。

那么从深度优先遍历和广度优先遍历进一步拓展,才有如下遍历方式:

  • 深度优先遍历
    • 前序遍历(递归法,迭代法)
    • 中序遍历(递归法,迭代法)
    • 后序遍历(递归法,迭代法)
  • 广度优先遍历
    • 层次遍历(迭代法)

在深度优先遍历中:有三个顺序,前中后序遍历, 有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。

这里前中后,其实指的就是中间节点的遍历顺序,只要大家记住 前中后序指的就是中间节点的位置就可以了。

看如下中间节点的顺序,就可以发现,中间节点的顺序就是所谓的遍历方式

  • 前序遍历:中左右
  • 中序遍历:左中右
  • 后序遍历:左右中

大家可以对着如下图,看看自己理解的前后中序有没有问题。

image-20220527195052631

四、二叉树的定义

package com.yzu.lee.treenode;

import org.junit.Test;

/**
 * @ClassName: TreeNode
 * @Description:树定义
 * @author: Leekuangyew
 * @date: 2022/5/22  9:34
 */
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

二叉树的递归遍历

144.二叉树的前序遍历

 package com.yzu.lee.treenode;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * @ClassName: PreorderTraversal
  * @Description:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
  * @author: Leekuangyew
  * @date: 2022/5/22  9:37
  */
 public class PreorderTraversal {
     public List<Integer> preorderTraversal(TreeNode root) {
         ArrayList<Integer> result = new ArrayList<>();
         preorder(root, result);
         return result;
     }
 
     private void preorder(TreeNode root, ArrayList<Integer> result) {
         if (root == null) {
             return;
         }
         result.add(root.val);
         preorder(root.left, result);
         preorder(root.right, result);
     }
 }

94.二叉树的中序遍历

 package com.yzu.lee.treenode;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * @ClassName: InorderTraversal
  * @Description:给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
  * @author: Leekuangyew
  * @date: 2022/5/22  9:46
  */
 public class InorderTraversal {
     public List<Integer> inorderTraversal(TreeNode root) {
         ArrayList<Integer> result = new ArrayList<>();
         inorder(root, result);
         return result;
     }
 
     private void inorder(TreeNode root, ArrayList<Integer> result) {
         if (root == null) {
             return;
         }
 
         inorder(root.left, result);
         result.add(root.val);
         inorder(root.right, result);
     }
 }

145.二叉树的后序遍历

 package com.yzu.lee.treenode;
 
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * @ClassName: PostorderTraversal
  * @Description:给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
  * @author: Leekuangyew
  * @date: 2022/5/22  9:50
  */
 public class PostorderTraversal {
     public List<Integer> postorderTraversal(TreeNode root) {
         ArrayList<Integer> result = new ArrayList<>();
         postorder(root, result);
         return result;
     }
 
     private void postorder(TreeNode root, ArrayList<Integer> result) {
         if (root == null) {
             return;
         }postorder(root.left, result);
         postorder(root.right, result);
         result.add(root.val);
     }
 }

二叉树的迭代遍历

144.二叉树的前序遍历

层次遍历使用迭代法才用队列,深度优先遍历时迭代法使用栈实现

思路:

  • 创建栈,并将根节点压入栈
  • while循环,当栈不为空,弹出栈顶节点,添加到结果数组,后判断右节点与左节点是否为空,不为空则加入
 //迭代法
 public List<Integer> preorderTraversal2(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     if (root == null) {
         return result;
     }
     Stack<TreeNode> stack = new Stack<>();
     stack.push(root);
     while (!stack.isEmpty()) {
         TreeNode node 
             = stack.pop();
         result.add(node.val);
         if (node.right != null) {
             stack.push(node.right);
         }
         if (node.left != null) {
             stack.push(node.left);
         }
     }
     return result;
 }

94.二叉树的中序遍历

思路:

在迭代的过程中,其实有两个操作:

  1. 处理:将元素放进result数组中
  2. 访问:遍历节点

为什么刚刚写的前序遍历的代码,不能和中序遍历通用呢,因为前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。

那么再看看中序遍历,中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。

那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。

  • 中序迭代遍历不需要先将root加入栈中
 //迭代法
 public List<Integer> inorderTraversal2(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     if (root == null) {
         return result;
     }
     Stack<TreeNode> stack = new Stack<>();
     TreeNode node = root;
     while (node != null || !stack.isEmpty()) {
         if (node != null) {
             stack.push(node);
             node = node.left;
         } else {
             node = stack.pop();
             result.add(node.val);
             node = node.right;
         }
     }
     return result;
 }

145.二叉树的后序遍历

  • 与前序相似,只需要将中右左的添加顺序改成中左右,最后反转结果数组
 //迭代法
 public List<Integer> postorderTraversal2(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     if (root == null) {
         return result;
     }
 
     Stack<TreeNode> stack = new Stack<>();
     stack.push(root);
     while (!stack.isEmpty()) {
         TreeNode node = stack.pop();
         result.add(node.val);
         if (node.left != null) {
             stack.push(node.left);
         }
         if (node.right != null) {
             stack.push(node.right);
         }
     }
     Collections.reverse(result);
     return result;
 }

二叉树的统一迭代法

144.二叉树的前序遍历

思路:

  • **将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记。**标记,就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。 这种方法也可以叫做标记法。
 //统一迭代法
 public List<Integer> preorderTraversal3(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     Stack<TreeNode> stack = new Stack<>();
 
     if (root != null) {
         stack.push(root);
     }
 
     while (!stack.isEmpty()) {
         TreeNode node = stack.peek();  //判断栈顶节点是否为null
         if (node != null) {
             stack.pop(); //如果不为null,则将栈顶弹出 并按中左右节点添加到栈里
             if (node.right != null) stack.push(node.right);//添加右节点
             if (node.left != null) stack.push(node.left);//添加左节点
             stack.push(node);//添加中节点
             stack.push(null);//添加完中节点后,需要对其进行处理 增加null标记
         } else {// 只有遇到空节点的时候,才将下一个节点放进结果集
             stack.pop();//弹出空节点
             node = stack.peek();//取出栈顶节点
             stack.pop();
             result.add(node.val);//加入结果集
         }
     }
     return result;
 }

94.二叉树的中序遍历

 //统一迭代法
 public List<Integer> inorderTraversal3(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     Stack<TreeNode> stack = new Stack<>();
 
     if (root != null) {
         stack.push(root);
     }
 
     while (!stack.isEmpty()) {
         TreeNode node = stack.peek();  //判断栈顶节点是否为null
         if (node != null) {
             stack.pop(); //如果不为null,则将栈顶弹出 并按左中右节点添加到栈里
             if (node.right != null) stack.push(node.right);//添加右节点
             stack.push(node);//添加中节点
             stack.push(null);//添加完中节点后,需要对其进行处理 增加null标记
             if (node.left != null) stack.push(node.left);//添加左节点
         } else {// 只有遇到空节点的时候,才将下一个节点放进结果集
             stack.pop();//弹出空节点
             node = stack.peek();//取出栈顶节点
             stack.pop();
             result.add(node.val);//加入结果集
         }
     }
     return result;
 }

145.二叉树的后序遍历

 //统一迭代法
 public List<Integer> postorderTraversal3(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     Stack<TreeNode> stack = new Stack<>();
 
     if (root != null) {
         stack.push(root);
     }
 
     while (!stack.isEmpty()) {
         TreeNode node = stack.peek();  //判断栈顶节点是否为null
         if (node != null) {
             stack.pop(); //如果不为null,则将栈顶弹出 并按中左右节点添加到栈里
             stack.push(node);//添加中节点
             stack.push(null);//添加完中节点后,需要对其进行处理 增加null标记
             if (node.right != null) stack.push(node.right);//添加右节点
             if (node.left != null) stack.push(node.left);//添加左节点
         } else {// 只有遇到空节点的时候,才将下一个节点放进结果集
             stack.pop();//弹出空节点
             node = stack.peek();//取出栈顶节点
             stack.pop();
             result.add(node.val);//加入结果集
         }
     }
     return result;
 }

102.二叉树的层序遍历

题意:给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

image-20220527204325050

思路:

  • 递归法:

    • 确定递归函数的参数和返回值 checkFun02(root, 0);
    • 确定终止条件: if (node == null) return;
    • 确定单层递归的逻辑:
      • 将传入的deep加一,表示所在的层数上升
      • 当结果集合的大小小于deep时,创建一个集合,放入结果结合中
      • 将当前节点的值填入到集合中对应的位置
      • 继续递归当前节点的左节点和右节点
  • 迭代法:

    • 判断根节点是否为空,不为空,则创建一个队列,将根节点放入到队列当中
    • 循环判断队列是否为空,如果不为空,则获取队列的大小,如果队列的size大于0,则弹出当前队首节点,并将该节点存到结果集合中,并将非空的左右子节点放入队列中
    • 每次循环将结果保存到集合中
package com.yzu.lee.treenode;

import com.sun.istack.internal.NotNull;
import com.sun.javafx.image.IntPixelGetter;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * @ClassName: LevelOrder
 * @Description:
 * @author: Leekuangyew
 * @date: 2022/5/25  13:53
 */
public class LevelOrder {
    private List<List<Integer>> result = new ArrayList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        //迭代法 利用队列
        checkFun01(root);
        //递归法
        checkFun02(root, 0);
        return result;
    }

    private void checkFun02(TreeNode node, int deep) {
        if (node == null) return;
        deep++;

        if (result.size() < deep) {
            ArrayList<Integer> list = new ArrayList<>();
            result.add(list);
        }
        result.get(deep - 1).add(node.val);

        checkFun02(node.left, deep);
        checkFun02(node.right, deep);
    }

    private void checkFun01(TreeNode root) {
        if (root == null) return;
        Queue<TreeNode> queue = new LinkedList<>();

        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();

            ArrayList<Integer> list = new ArrayList<>();
            while (size > 0) {
                TreeNode node = queue.poll();
                list.add(node.val);

                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
                size--;
            }
            result.add(list);
        }
    }
}

107.二叉树的层次遍历II

题意:给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

image-20220527205535544

思路:

  • 递归法,层序遍历,然后反转
  • 迭代法,层序遍历,然后反转
package com.yzu.lee.treenode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName: LevelOrderBottom
 * @Description:给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
 * @author: Leekuangyew
 * @date: 2022/5/25  15:09
 */
public class LevelOrderBottom {
    List<List<Integer>> result = new ArrayList<>();

    public List<List<Integer>> levelOrderBottom(TreeNode root) {

        levelOrder(root, 0);
        Collections.reverse(result);
        return result;

    }

    private void levelOrder(TreeNode node, int deep) {
        if (node == null) return;
        int size = result.size();
        deep++;

        if (size < deep) {
            List<Integer> list = new ArrayList<>();
            result.add(list);
        }
        result.get(deep - 1).add(node.val);

        if (node.left != null) levelOrder(node.left, deep);
        if (node.right != null) levelOrder(node.right, deep);
    }
}

199. 二叉树的右视图

题意:给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

image-20220527210138056

思路:

  • 利用BFS进行层次遍历,记录下每层的最后一个元素。
  • DFS
package com.yzu.lee.treenode;

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;

/**
 * @ClassName: RightSideView
 * @Description:给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
 * @author: Leekuangyew
 * @date: 2022/5/25  17:21
 */
public class RightSideView {
    List<List<Integer>> resList = new ArrayList<List<Integer>>();

    public List<Integer> rightSideView(TreeNode root) {
        rightSide(root, 0);

        ArrayList<Integer> result = new ArrayList<>();
        for (List<Integer> list : resList) {
            result.add(list.get(list.size() - 1));
        }

        return result;
    }

    private void rightSide(TreeNode node, int deep) {
        if (node == null) return;
        deep++;

        if (resList.size() < deep) {
            List<Integer> list = new ArrayList<>();
            resList.add(list);
        }
        resList.get(deep - 1).add(node.val);

        if (node.left != null) rightSide(node.left, deep);
        if (node.right != null) rightSide(node.right, deep);
    }
}

637.二叉树的层平均值

题意:给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

image-20220527210747623

思路:

  • 利用BFS进行层次遍历,然后对每一层的结果进行取平均值操作
package com.yzu.lee.treenode;

import com.sun.org.apache.bcel.internal.generic.NEW;
import org.w3c.dom.ls.LSException;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: AverageOfLevels
 * @Description:
 * @author: Leekuangyew
 * @date: 2022/5/25  17:32
 */
public class AverageOfLevels {

    List<List<Integer>> resList = new ArrayList<List<Integer>>();

    public List<Double> averageOfLevels(TreeNode root) {
        averageOfLevels(root, 0);
        ArrayList<Double> result = new ArrayList<>();
        for (List<Integer> list : resList) {
            int size = list.size();
            double sum = 0;
            for (Integer integer : list) {
                sum += integer;
            }
            Double res =  sum / (double) size;
            result.add(res);
        }
        return result;
    }

    private void averageOfLevels(TreeNode node, int deep) {
        if (node == null) return;
        deep++;
        int size = resList.size();

        if (size < deep) {
            ArrayList<Integer> list = new ArrayList<>();
            resList.add(list);
        }
        resList.get(deep - 1).add(node.val);

        if (node.left != null) averageOfLevels(node.left, deep);
        if (node.right != null) averageOfLevels(node.right, deep);
    }
}

429.N叉树的层序遍历

题意:给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

image-20220527210954880

思路:

  • 利用BFS的递归法层次遍历,只有对于操作子节点的方式不同
package com.yzu.lee.treenode;

import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: LevelOrderT
 * @Description:给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
 * 树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
 * @author: Leekuangyew
 * @date: 2022/5/25  18:21
 */
public class LevelOrderT {
    List<List<Integer>> result = new ArrayList<>();

    public List<List<Integer>> levelOrder(Node root) {

        levelOrder(root, 0);
        return result;
    }

    private void levelOrder(Node node, int deep) {
        if (node == null) return;
        deep++;
        int size = result.size();

        if (size < deep) {
            ArrayList<Integer> list = new ArrayList<>();
            result.add(list);
        }
        result.get(deep - 1).add(node.val);

        if (node.children != null) {
            for (Node child : node.children) {
                levelOrder(child, deep);
            }
        }
    }
}

515.在每个树行中找最大值

题意:给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

image-20220527211307762

思路:

  • 利用BFS进行递归层次遍历,定义一个Map来存储每一层的最大值
package com.yzu.lee.treenode;

import com.sun.org.apache.bcel.internal.generic.NEW;
import org.junit.Test;

import java.util.*;

/**
 * @ClassName: LargestValues
 * @Description:给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
 * @author: Leekuangyew
 * @date: 2022/5/25  18:37
 */
public class LargestValues {
    Map<Integer, Integer> resList = new HashMap<>();

    public List<Integer> largestValues(TreeNode root) {
        largestValues(root, 0);
        ArrayList<Integer> list = new ArrayList<>();
        int i = 0;
        while (resList.containsKey(i)) {
            list.add(resList.get(i));
            i++;
        }
        return list;
    }

    private void largestValues(TreeNode node, int deep) {
        if (node == null) return;
        deep++;

        if (resList.containsKey(deep - 1)) {
            resList.put(deep - 1, Math.max(resList.get(deep - 1), node.val));
        } else {
            resList.put(deep - 1, node.val);
        }


        if (node.left != null) largestValues(node.left, deep);
        if (node.right != null) largestValues(node.right, deep);
    }
}

116.填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

image-20220527211844477

思路:

  • 利用BFS进行迭代层次遍历,在迭代过程中,将每一层中的节点的next等于队列的头节点 node.next = queue.peek();
package com.yzu.lee.treenode.node;

/**
 * @ClassName: Node
 * @Description:
 * @author: Leekuangyew
 * @date: 2022/5/25  20:12
 */
public class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {
    }

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, Node _left, Node _right, Node _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
}
package com.yzu.lee.treenode.node;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @ClassName: Connect
 * @Description:
 * @author: Leekuangyew
 * @date: 2022/5/25  20:12
 */
public class Connect {
    public Node connect(Node root) {
        Queue<Node> queue = new LinkedList<>();
        if (root == null) return root;

        queue.offer(root);

        while (!queue.isEmpty()) {
            int size = queue.size();

            while (size > 0) {
                Node node = queue.poll();

                size--;

                if (size > 0) {
                    node.next = queue.peek();
                }
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
        }
        return root;
    }
}

117.填充每个节点的下一个右侧节点指针II

题意:给定一个二叉树

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

image-20220527212359302

思路:

  • 与116题类似
package com.yzu.lee.treenode.node;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @ClassName: Connect
 * @Description:
 * @author: Leekuangyew
 * @date: 2022/5/25  20:12
 */
public class Connect {
    public Node connect(Node root) {
        Queue<Node> queue = new LinkedList<>();
        if (root == null) return root;

        queue.offer(root);

        while (!queue.isEmpty()) {
            int size = queue.size();

            while (size > 0) {
                Node node = queue.poll();

                size--;

                if (size > 0) {
                    node.next = queue.peek();
                }
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
        }
        return  root;
    }
}

226.翻转二叉树

题意:翻转一棵二叉树

image-20220527212521845

思路:

  • 利用DFS进行递归 前序
    • 确定递归函数的参数和返回值 invertTree(TreeNode root)
    • 确定终止条件: if (root == null) return root;
    • 确定单层递归的逻辑:swap(root); 并返回root。
  • 利用BFS进行迭代
    • 从第一层开始,依次往下交换左右节点
package com.yzu.lee.treenode;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @ClassName: InvertTree
 * @Description:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
 * @author: Leekuangyew
 * @date: 2022/5/25  22:35
 */
public class InvertTree {
//    public TreeNode invertTree(TreeNode root) {
//        //深度优先DFS
//        if (root == null) return root;
//        swap(root);
//        invertTree(root.left);
//        invertTree(root.right);
//        return root;
//    }
//
//    private void swap(TreeNode root) {
//        TreeNode temp = root.left;
//        root.left = root.right;
//        root.right = temp;
//    }

    public TreeNode invertTree(TreeNode root) {
        //广度优先 BFS
        if (root == null) return null;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            int size = queue.size();

            while (size-- > 0) {
                TreeNode node = queue.poll();
                swap(node);
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
        }
        return root;
    }

    private void swap(TreeNode node) {
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leekuangyee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值