代码随想录算法训练营Day13

二叉树

二叉树的递归遍历

class Solution {  
    public List<Integer> preorderTraversal(TreeNode root) {  
        ArrayList<Integer> list = new ArrayList<>();  
        preorder(root,list);  
        return list;  
    }  
    public void preorder(TreeNode root,ArrayList<Integer> list){  
        if(root == null){  
            return;  
        }  
        list.add(root.val);//前中后序遍历的区别就在这里的顺序
        preorder(root.left,list);  
        preorder(root.right,list);  
    }  
}

二叉树的非递归遍历

二叉树的非递归遍历主要是通过栈来模拟递归调用的过程,从而实现对二叉树的遍历。

前序遍历

先将根节点入栈,在循环中弹出栈顶节点并访问,然后将其右子节点和左子节点依次入栈(注意顺序)

class Solution {  
    public List<Integer> preorderTraversal(TreeNode root) {  
        List<Integer> list = new ArrayList<>();  
        if(root == null){  
            return list;  
        }  
        Stack<TreeNode> stack = new Stack<>();  
        stack.push(root);  
        while(!stack.isEmpty()){//这里不需要写root==null的判断,因为上面已经写了  
            TreeNode cur = stack.pop();  
            list.add(cur.val);  
            if(cur.right!=null){  
                stack.push(cur.right);  
            }  
            if(cur.left!=null){  
                stack.push(cur.left);  
            }  
        }  
        return list;  
    }  
}

后序遍历

修改上面的先序遍历即可
先序:中左右 先序':中右左 后序:左右中
即为先序'的倒序

class Solution {  
    public List<Integer> postorderTraversal(TreeNode root) {  
        List<Integer> list = new ArrayList<>();  
        if(root == null){  
            return list;  
        }  
        Stack<TreeNode> stack = new Stack<>();  
        Stack<TreeNode> collect = new Stack<>();  
        stack.push(root);  
        while(!stack.isEmpty()){//这里不需要写root==null的判断,因为上面已经写了  
            TreeNode cur = stack.pop();//每pop一个,本来应该输出,但是我把他保存在另一个栈中  
            collect.push(cur);
            if(cur.left!=null){  
                stack.push(cur.left);  
            }  
            if(cur.right!=null){  
                stack.push(cur.right);  
            }  
        }  
        while(!collect.isEmpty()){  
            TreeNode cur = collect.pop();  
            list.add(cur.val);  
        }
  
        return list;//这里也可以用另一个栈接收!输出即为逆序  
    }  
}

中序遍历

对每个根节点而言,在处理完其左子树之后,才会处理根节点,然后再处理其右子树,栈的作用是记录遍历过的元素

class Solution {  
    public List<Integer> inorderTraversal(TreeNode root) {  
        ArrayList<Integer> result = new ArrayList<>();  
        if(root == null){  
            return result;  
        }  
        Stack<TreeNode> stack = new Stack<>();  
        TreeNode cur = root;  
        while(cur!=null||!stack.isEmpty()){  
            if(cur!= null){  
                stack.push(cur);  
                cur = cur.left;  
            }else{  
                cur = stack.pop();  
                result.add(cur.val);  
                cur = cur.right;  
            }  
        }  
        return result;  
    }  
}

层序遍历

public class Solution {  
    public List<Integer> lo(TreeNode root) {  
        // 存储层序遍历结果  
        List<Integer> result = new ArrayList<>();  
        if (root == null) {  
            return result; // 如果根节点为空,直接返回空列表  
        }  
  
        // 使用队列进行层序遍历  
        Queue<TreeNode> queue = new LinkedList<>();  
        queue.offer(root);  
  
        while (!queue.isEmpty()) {  
            // 弹出队列头部元素  
            TreeNode currentNode = queue.poll();  
            result.add(currentNode.val); // 记录当前节点值  
  
            // 只有非空子节点才加入队列  
            if (currentNode.left != null) {  
                queue.offer(currentNode.left);  
            }  
            if (currentNode.right != null) {  
                queue.offer(currentNode.right);  
            }  
        }  
  
        return result; // 返回最终结果列表  
    }  
}

下面要求按层输出,例如:[1],[2,3]...

//在本题中,需要有一个size变量来记录队列中的层的元素个数  
class Solution {  
    public List<List<Integer>> levelOrder(TreeNode root) {  
        // 存储层序遍历结果,注意这里二维列表的定义方式
        List<List<Integer>> result = new ArrayList<List<Integer>>();  
        if (root == null) {  
            return result; // 如果根节点为空,直接返回空列表  
        }  
  
        // 使用队列进行层序遍历  
        Queue<TreeNode> queue = new LinkedList<>();  
        queue.offer(root);  
  
        while (!queue.isEmpty()) {  
            // 弹出队列头部元素  
            int size = queue.size();  
            List<Integer> list = new ArrayList<>();
            //当循环次数固定时,用for循环
            for(int i = 0;i<size;i++){  
                TreeNode currentNode = queue.poll();  
                list.add(currentNode.val); // 记录当前节点值  
  
                //只有非空子节点才加入队列!!!
                if (currentNode.left != null) {  
                    queue.offer(currentNode.left);  
                }  
                if (currentNode.right != null) {  
                    queue.offer(currentNode.right);  
                }  
            }  
            result.add(list);  
  
        }  
  
        return result; // 返回最终结果列表  
    }  
}
posted @ 2025-04-07 19:00  Anson_502  阅读(24)  评论(0)    收藏  举报