首先是层序遍历的递归方案
public void digui(TreeNode root, int deep) {
// 这里去弄每一层
if (root == null) {
return;
}
deep += 1;
if (ress.size() < deep) {
List<Integer> demo = new ArrayList<Integer>();
ress.add(demo);
}
// 这里是判断增加层数
// 总体就是进去一层就计数器增加一层,每一层对应的数组下表是固定的,可以确定
// 然后往里面增加数
ress.get(deep - 1).add(root.val);
digui(root.left, deep);
digui(root.right, deep);
}
对于层序遍历的递归实现主要的重点就是会有一个代表层数的tag所以,检索的先后顺序就不是很重要,因为有deep这个变量去记载当前的层数,当遍历进入到一个新的递归时候,会把deep加一,然后判断当前的res里面是否有代表这个deep的二级数组,没有就增加,有就把val存进去即可。
队列的层序遍历
public void duilie(TreeNode root){
Queue<TreeNode> que = new LinkedList<>();
//这是用来临时存放节点的队列
if (root==null) {
return;
}
que.offer(root);
while (!que.isEmpty()) {
List<Integer> temp=new LinkedList<>();
int len=que.size();
while (len>0) {
TreeNode demo=que.poll();
temp.add(demo.val);
if (demo.left!=null) {
que.offer(demo.left);
}
if (demo.right!=null) {
que.offer(demo.right);
}
len-=1;
}
resList.add(temp);
}
}
队列的层序遍历思想就是,一层一层的,当第一次带一个新的层次,我们会记录当前的len是多少,没处理一个节点就把len减去一,处理完后,进入下一个层接着处理就行了。当当前的队列为空,证明结束了,就直接return即可,首先判断root不为空就加入,然后这是满足进入while的初始条件,进入后,就可以按照重复的步骤了,去记载len然后接着while。
二叉树的层序遍历倒着输出
public void digui(TreeNode root,int deep){
//这里去弄每一层
if (root==null) {
return;
}
deep+=1;
if (ress.size()<deep) {
List<Integer> demo=new ArrayList<Integer>();
ress.add(demo);
}
//这里是判断增加层数
//总体就是进去一层就计数器增加一层,每一层对应的数组下表是固定的,可以确定
//然后往里面增加数
ress.get(deep-1).add(root.val);
digui(root.left, deep);
digui(root.right, deep);
}
其实还都是正常和遍历,然后对其结果进行反转,
要不就是去用队列遍历,然后加入每个结果用头插法进行加入,最后的结果不用反转。
交换节点
import java.lang.reflect.Array;
import java.util.ArrayDeque;
public class day15_226_翻转二叉数 {
public static void main(String[] args) {
}
public static 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;
}
}
public TreeNode fanzhuan(TreeNode root){
if (root!=null) {
digui(root);
}
return root;
}
public static void digui(TreeNode root){
//递归前序遍历的翻转
//先翻转然后左右
if (root==null) {
return;
}
TreeNode demo=root.left;
root.left=root.right;
root.right=demo;
//这是交换过程
digui(root.left);
digui(root.right);
}
public static void chengxufanzhuan(TreeNode root){
if (root==null) {
return
;
}
ArrayDeque<TreeNode> demo=new ArrayDeque<>();
//这是临时存放的队列
// TreeNode cur=root;
demo.offer(root);
while (!demo.isEmpty()) {
int len=demo.size();
while (len>0) {
TreeNode temp=demo.poll();
TreeNode demo2=temp.left;
temp.left=temp.right;
temp.right=demo2;
//这里是交换
if (temp.left!=null) {
demo.offer(temp.left);
}
if (temp.right!=null) {
demo.offer(temp.right);
}
len-=1;
}
//层序的思想就是层序遍历每一个然后交换子节点,思想比较简单。
}
}
}
对称二叉数
public boolean isSymmetric1(TreeNode root) {
return compare(root.left, root.right);
}
private boolean compare(TreeNode left, TreeNode right) {
if (left == null && right != null) {
return false;
}
if (left != null && right == null) {
return false;
}
if (left == null && right == null) {
return true;
}
if (left.val != right.val) {
return false;
}
// 比较外侧
boolean compareOutside = compare(left.left, right.right);
// 比较内侧
boolean compareInside = compare(left.right, right.left);
return compareOutside && compareInside;
}
这是递归法,还有就是用双端队列的,双端队列要把空节点也加入,这样才能判断是不是对称,有一个小知识点,link dque可以加null 但是arraydeque不能加null元素