二叉树

二叉树概念

二叉树:每个节点最多有两个子节点

满二叉树:深度为K,有2^k-1个节点

完全二叉树:满二叉树属于完全二叉树,最后一层可满可不满,不满只可右部分缺失,其余层是满的

平衡二叉树:一棵空树或者左右子树的高度差的绝对值不能超过1

二分查找树:左子树节点的值比该节点的值小,右子树节点的值比该节点的值大

 

前序遍历

首先访问根节点,然后遍历其左节点,再遍历其右节点

实现方式 1:递归,先访问根节点,然后分别递归调用左子树和右子树

 public void preOrder(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        System.out.print(treeNode.getValue());

        preOrder(treeNode.getLeft());

        preOrder(treeNode.getRight());

    }

  

实现方式 2:迭代,本质上就是模拟递归实现栈的存储过程。沿着左子树向下访问到叶子节点;从栈中取出栈顶元素,向右转弯,执行第一步逻辑

 private void preOrderIteration(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        Stack<TreeNode> treeNodeStack=new Stack<>();
        
        while (treeNode!=null){
            
            while (treeNode!=null){

                System.out.println(treeNode.getValue());
                treeNodeStack.push(treeNode);
                treeNode=treeNode.getLeft();

            }
            
            while (!treeNodeStack.empty() && treeNode==null){

                treeNode=treeNodeStack.pop();
                treeNode=treeNode.getRight();
                
            }

        }

    }

  

中序遍历

实现方式 1:递归,首先遍历左子树、然后访问根节点,最后遍历右子树

private void inOrder(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        inOrder(treeNode.getLeft());

        System.out.print(treeNode.getValue());

        inOrder(treeNode.getRight());

    }

  

实现方式 2:迭代,与前序遍历相似,只是访问节点时机不同。沿着左子树向下访问到根节点,访问栈顶元素,向右转弯,执行第一步逻辑

private void inOrderIteration(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        Stack<TreeNode> treeNodeStack=new Stack<>();

        while (treeNode!=null){

            while (treeNode!=null){
                
                treeNodeStack.push(treeNode);
                treeNode=treeNode.getLeft();

            }

            while (!treeNodeStack.empty() && treeNode==null){

                treeNode=treeNodeStack.pop();
                System.out.println(treeNode.getValue());
                treeNode=treeNode.getRight();

            }

        }

    }

  

后序遍历

实现方式 1:递归,首先遍历左子树、然后遍历右子树,最后访问根结点。

 private void afterOrder(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        afterOrder(treeNode.getLeft());

        afterOrder(treeNode.getRight());

        System.out.print(treeNode.getValue());
    }

  

实现方式 2:迭代,后序遍历的迭代实现又分为单栈实现和双栈实现

单栈实现:沿着左子树向下访问到叶子节点。栈顶元素出栈,判断是否存在右子树:若存在,当前节点重复入栈,并且其right引用置null,以免下次出栈再次遍历其右子树;若不存在,访问当前节点。右转弯到右子树上,回到第1步或2步。

 private void postOrderIteration(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        Stack<TreeNode> treeNodeStack=new Stack<>();

        while (treeNode!=null){

            while (treeNode!=null){

                treeNodeStack.push(treeNode);
                treeNode=treeNode.getLeft();

            }

            while (!treeNodeStack.empty() && treeNode==null){

                treeNode = treeNodeStack.pop();
                TreeNode rightNode=treeNode.getRight();

                if(rightNode==null){
                    System.out.print(treeNode.getValue());
                }else {
                    treeNodeStack.push(treeNode);
                    treeNode.setRight(null);
                }

                treeNode=rightNode;
            }

        }

    }

  

双栈实现:stack1用于规划下一个将要访问的节点,stack2保存后序遍历节点访问的顺序

 private void postOrderIteration2(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        Stack<TreeNode> stack1=new Stack<>();
        Stack<TreeNode> stack2=new Stack<>();
        stack1.push(treeNode);

        while (!stack1.empty()){

            //下一个访问的节点
            treeNode= stack1.pop();
            stack2.push(treeNode);

            //先入栈左子树节点
            if(treeNode.getLeft()!=null){
                stack1.push(treeNode.getLeft());
            }

            //再入栈右子树节点,这样下一个访问的将是右子树
            if(treeNode.getRight()!=null){
                stack1.push(treeNode.getRight());
            }

        }

        //stack2元素出栈顺序即是后序遍历顺序
        while (!stack2.empty()){
            System.out.print(stack2.pop().getValue());
        }

    }

  

 

分层遍历

 private void floorOrder(TreeNode treeNode){

        if(treeNode==null){
            return;
        }

        LinkedList<TreeNode> linkedList=new LinkedList<>();
        linkedList.add(treeNode);

        TreeNode currectNode;

        while (linkedList!=null && linkedList.size()>0){

            currectNode=linkedList.poll();
            if(currectNode!=null){

                System.out.print(currectNode.getValue());
                linkedList.add(currectNode.getLeft());
                linkedList.add(currectNode.getRight());
            }

        }
    }

  

posted @ 2020-06-24 11:36  蹦蹦郭  阅读(151)  评论(0编辑  收藏  举报