zoukankan      html  css  js  c++  java
  • 二叉树

    二叉树概念

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

    满二叉树:深度为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());
                }
    
            }
        }
    

      

  • 相关阅读:
    套接字描述符在多进程和多线程下的共享
    广播和多播
    原始套接字和数据链路层访问
    Libevent:11使用Libevent的DNS上层和底层功能
    Lib1vent:10链接监听器接受TCP链接
    Libevent:9Evbuffers缓存IO的实用功能
    Libevent:7Bufferevents基本概念
    python生成url测试用例
    OMD开源监控软件
    iptable防范ddos攻击
  • 原文地址:https://www.cnblogs.com/BounceGuo/p/13183760.html
Copyright © 2011-2022 走看看