zoukankan      html  css  js  c++  java
  • 二叉树学习总结

    这几天刷的算法题都是二叉树相关的,这里就放一点二叉树的知识:

    首先是遍历:

    前序遍历:根结点 ---> 左子树 ---> 右子树

    中序遍历:左子树---> 根结点 ---> 右子树

    后序遍历:左子树 ---> 右子树 ---> 根结点

    层次遍历:一层一层输出

    1.前序遍历:根左右

    递归

     public void inorder(TreeNode root) {
            if (root == null) {
                return;
            }
            System.out.println(root.val);
            inorder(root.left, res);
            inorder(root.right, res);
        }

    非递归:

     如果采用非递归的实现,顺序不变依然是根然后左右,因为是先左之后还要找到根的右孩子,所以要保存根节点,采用栈进行保存。

    从最开始的根节点开始,

    1。如果不是空,那么输出该根节点数据同时将该节点入栈,并将其左孩子节点定为目标节点

    2。然后再判断当前节点是否为空,如果是空则出栈,将出栈的结点的右孩子节点定位目标节点,否则重复第一步直到栈空且结点为空

    public void preOrderTraverse2(TreeNode root) {  
            LinkedList<TreeNode> stack = new LinkedList<>();  
            TreeNode pNode = root;  
            while (pNode != null || !stack.isEmpty()) {  
                if (pNode != null) {  
                    System.out.print(pNode.val+"  ");  
                    stack.push(pNode);  
                    pNode = pNode.left;  
                } else { //pNode == null && !stack.isEmpty()  
                    TreeNode node = stack.pop();  
                    pNode = node.right;  
                }  
            }  
        }  

    2.中序遍历:左根右

    递归

     public void inorder(TreeNode root) {
            if (root == null) {
                return;
            }
            System.out.println(root.val);
            inorder(root.left, res);
            inorder(root.right, res);
        }

    非递归:

     和前序遍历相似,只是将输出根节点的时刻放到右孩子之前

    public void preOrderTraverse2(TreeNode root) {  
            LinkedList<TreeNode> stack = new LinkedList<>();  
            TreeNode pNode = root;  
            while (pNode != null || !stack.isEmpty()) {  
                if (pNode != null) {  
                    stack.push(pNode);  
                    pNode = pNode.left;  
                } else { //pNode == null && !stack.isEmpty()  
                    TreeNode node = stack.pop();  
                    System.out.print(node.val+"  ");  
                    pNode = node.right;  
                }  
            }  
        }

    3.后序遍历:左右根

    递归

    public void inorder(TreeNode root) {
            if (root == null) {
                return;
            }
            inorder(root.left, res);
            inorder(root.right, res);
            System.out.println(root.val);
        }

    非递归

     后序遍历的非递归是最难的,要保证左右全部访问之后再重新回到根节点,

    不太好写,等以后搞明白了再来吧

    4.层次遍历:

    比较简单,用队列保存结点就可以,需要注意的是,一定要注意root为空或者左右孩子为空的情况

    class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            if(root==null){
                return new ArrayList<>();
            }
           Queue<TreeNode> queue=new LinkedList<>();
           List<List<Integer>> res=new ArrayList<>();
           queue.add(root);
           while(!queue.isEmpty()){
               int len=queue.size();
                List<Integer> r=new ArrayList<>();
               for(int i=0;i<len;i++){
                TreeNode node=queue.poll();
                 r.add(node.val);
                 if(node.left!=null)
                 queue.add(node.left);
                 if(node.right!=null)
                 queue.add(node.right);
               }
               res.add(r);
           }
           return res;
        }
    }

     5.二叉树左右孩子交换

    层次:

    class Solution {
        public TreeNode invertTree(TreeNode root) {
            if(root==null){
                return root;
            }
        Queue<TreeNode> queue=new LinkedList<>();
        TreeNode res=root;
        queue.add(root);
        while(!queue.isEmpty()){
            int len=queue.size();
            for(int i=0;i<len;i++){
                TreeNode node=queue.poll();
                if(node.left!=null){queue.add(node.left);}
                if(node.right!=null){queue.add(node.right);}
                TreeNode childnode=node.left;
                node.left=node.right;
                node.right=childnode;
            }
        }
        return res;
        }
    }

    先序:

    class Solution {
            // 先序遍历--从顶向下交换
            public TreeNode invertTree(TreeNode root) {
                if (root == null) return null;
                // 保存右子树
                TreeNode rightTree = root.right;
                // 交换左右子树的位置
                root.right = invertTree(root.left);
                root.left = invertTree(rightTree);
                return root;
            }
        }
  • 相关阅读:
    一位区域销售经理百条经验手记
    PAIP.FLEX与JAVA数据对应关系.txt
    转:java生成EXCEL表格(POI vs JXL)
    逆向分析工具介绍
    applet与SERLET交互...
    AT命令集(
    关于WINDOWS超级终端的使用来调试MODEM,串口.
    poj1331
    poj1338
    poj1325
  • 原文地址:https://www.cnblogs.com/PPGwo/p/13668949.html
Copyright © 2011-2022 走看看