二叉树的层序遍历&&二叉树的右视图&&填充每个节点的下一个右侧节点指针及II(Java)

二叉树的层序遍历

思路:分层—从上到下、从左到右,用队列。每一层放入一个list,所有的list放入结果集,所以要有两个循环。
外层循环:队列不为空
内层循环:循环该层的节点个数,直接用size获取
(注意:如果任何操作有关分层次,都需要两个循环)

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if(root == null){
            return res; // 不要忘记
        }
        que.offer(root);
        while(!que.isEmpty()){
            int size = que.size();
            List<Integer> sub = new ArrayList<>();
            for(int i = 0; i < size; i++){
                root = que.poll();
                sub.add(root.val);
                if(root.left != null){
                    que.offer(root.left);
                }
                if(root.right != null){
                    que.offer(root.right);
                } 
            }
            res.add(sub);
        }
        return res;
    }
    
}

二叉树的层序遍历II(Java)

倒着遍历,提供一下思路:

  1. 每次在结果集中添加时,都添加到首位。如:res.add(0, sub); //在索引0出加入sub–往前加
  2. 交换算法(注意设置List使用set,get)
int left = 0;
        int right = res.size() - 1;
        while(left < right){
            List<Integer> temp = res.get(right);
            res.set(right, res.get(left));
            res.set(left, temp);
            left++;
            right--;
        }
  1. 库函数:Collections.reverse(res);
  2. 新建一个res,指针倒序排
    题目代码如下:
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> res= new ArrayList<>();
        if(root == null){
            return res;
        }
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        while(!que.isEmpty()){
            List<Integer> sub = new ArrayList<>();
            int size = que.size();
            for(int i = 0; i < size; i++){
                root = que.poll();
                sub.add(root.val);
                if(root.left != null) que.offer(root.left);
                if(root.right != null) que.offer(root.right);
            }
            res.add(0, sub); //在索引0出加入sub--往前加
        }
        return res;
    }
}

二叉树的右视图(Java)

思路:当循环到每一层的最后位置才会记录到结果集(广度搜索)

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null){
            return res;
        }
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        while(!que.isEmpty()){
            int size = que.size();
            for(int i = 0; i < size; i++){ //每一层输出也是循环
                root = que.poll();
                if(root.left != null) que.offer(root.left);
                if(root.right != null) que.offer(root.right);
                if(i == size - 1) res.add(root.val);
            }
            
        }
        return res;
    }
}

填充每个节点的下一个右侧节点指针(Java)

方法1:层次迭代

/*
// Definition for a Node.
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;
    }
};
*/

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return root;
        }
        Queue<Node> que = new LinkedList<>();
        que.offer(root);
        while(!que.isEmpty()){
            int size = que.size();
            for(int i = 0; i < size; i++){
                Node root1 = que.poll();
                if(root1.left != null) que.offer(root1.left);
                if(root1.right != null) que.offer(root1.right);
                if(i == size - 1){
                    root1.next = null;
                }
                else{
                    root1.next = que.peek();
                }
            }
        }
        return root;
    }
}

方法2:完美二叉树独有做法-减少复杂度

/*
// Definition for a Node.
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;
    }
};
*/

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return root;
        }
        Node temp = root;
        while(temp.left != null){
            Node cur = temp;
            while(cur != null){
                cur.left.next = cur.right; //共同的父节点对的下边相连
                if(cur.next != null){
                    cur.right.next = cur.next.left; //不同的父节点对的下边相连
                }
                cur = cur.next;
            }
            temp = temp.left;
        }

        return root;
    }
}

填充每个节点的下一个右侧节点指针II(Java)

思路:使用虚拟头结点(原因是并不是都有left)

/*
// Definition for a Node.
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;
    }
};
*/

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return root;
        }
        Node temp = root;
        
        while(temp != null){
            Node dummyhead = new Node(); //下一层的虚拟头结点
            Node dummy = dummyhead;
            for(Node cur = temp; cur != null; cur = cur.next){
                //循环条件跟dummy无关
                if(cur.left != null){
                    dummy.next = cur.left;
                    dummy = dummy.next;
                }
                if(cur.right != null){
                    dummy.next = cur.right;
                    dummy = dummy.next;
                }
            }
            temp = dummyhead.next; // 移动到下一层的实际头节点处(妙啊!!)
        }
        return root;
    }
}

写博客的目的是每日督促并记录刷题,也欢迎大家批评指正~(day16)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值