• 二叉树的遍历(递归实现与非递归实现java)


    二叉树的遍历递归实现比较简单

    二叉树的非递归实现

      先根遍历

      中根遍历(两种实现方式)

      后根遍历(比较复杂)

    package com.sun.util;
    
    import java.lang.reflect.Method;
    import java.util.*;
    
    class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int x){
            val=x;
        }
        public TreeNode getLeft() {
            return left;
        }
        public void setLeft(TreeNode left) {
            this.left = left;
        }
        public TreeNode getRight() {
            return right;
        }
        public void setRight(TreeNode right) {
            this.right = right;
        }
        
    }
    public class Solution {
        
        public TreeNode[] initTree(){
            TreeNode[] tree=new TreeNode[11];
            for(int i=0;i<tree.length;i++){
                tree[i]=new TreeNode(i+1);
            }
            tree[0].left=tree[1];
            tree[0].right=tree[2];
            tree[1].left=tree[3];
            tree[1].right=tree[4];
            tree[2].left=tree[5];
            tree[2].right=tree[6];
            
    //        tree[4].left=tree[7];
    //        tree[3].right=tree[8];
    //        
    //        tree[8].left=tree[9];
    //        tree[8].right=tree[10];
            
            tree[4].left=tree[7];
            tree[4].right=tree[8];
            
            tree[8].left=tree[9];
            tree[8].right=tree[10];
            return tree;
            
        }
        
    //    一递归遍历
    //    1.先根遍历
        public void preOrderRecursion(TreeNode root, List<Integer> nodeList){
            if (root!=null){
                nodeList.add(root.val);
                preOrderRecursion(root.left, nodeList);
                preOrderRecursion(root.right,nodeList);
            }
            
        }
    //    2.中根遍历
        public void inOrderRecursion(TreeNode root, List<Integer> nodeList){
            if (root!=null){
                inOrderRecursion(root.left, nodeList);
                nodeList.add(root.val);
                inOrderRecursion(root.right,nodeList);
            }
            
        }
    //    3.后根遍历
        public void afterOrderRecursion(TreeNode root, List<Integer> nodeList){
            if (root!=null){
                afterOrderRecursion(root.left, nodeList);
                afterOrderRecursion(root.right,nodeList);
                nodeList.add(root.val);
            }
            
        }
    //    二 非递归遍历(栈实现)
                
    //    1.先根遍历_1
        public void preOrderStack(TreeNode root, List<Integer> nodeList){
            Stack<TreeNode> nodeStack = new Stack<TreeNode>();
            TreeNode currentNode=root;
            while(!nodeStack.isEmpty()||currentNode!=null){
                while(currentNode!=null){
                    nodeList.add(currentNode.val);System.out.println(currentNode.val);
                    nodeStack.push(currentNode);
                    currentNode=currentNode.left;
                }
                if(!nodeStack.isEmpty()){
                    currentNode = nodeStack.pop();
                    currentNode = currentNode.right;
                }
            }
        }    
            
        
    //    2.中根遍历_1
        public void inOrderStackOne(TreeNode root, List<Integer> nodeList){
            Stack<TreeNode> nodeStack = new Stack<TreeNode>();
            nodeStack.push(root);
            TreeNode peekNode,popNode;
            while(!nodeStack.isEmpty()){// 第一个while循环
                peekNode = nodeStack.peek();
                while(peekNode!=null){// 第二个while循环
                    nodeStack.push(peekNode.left);
                    peekNode=nodeStack.peek();
                }
                nodeStack.pop();
                if(!nodeStack.isEmpty()){ 
                    // 这个if判断主要是因为,当最后一个节点pop出战之后,还会把最后一个节点的右孩子入站,但是值为null,
                    //导致会进入第一个while循环,不会进入第二个while循环,详细解释如下:
                    /*当popNode为最后一个遍历到的节点的时候, 
                    nodeStack.push(popNode.right);使栈还存在一个null,栈不为空,
                    可以进入第一个while循环,
                    但是此时由于栈里面的元素只剩下null,所以peekNode=nodeStack.peek()=null
                    不会进入的二个while循环
                    当执行到nodeStack.pop()之后,此时栈为空,这个时候就应该停止算法了.如果不加if条件,则会进入if体内,再次调用nodeStack.pop()出错
                    */
                    popNode = nodeStack.pop();
                    nodeList.add(popNode.val);
                    nodeStack.push(popNode.right);
                }
            }
        }
        
    //    2.中根遍历_2
        public void inOrderStackTwo(TreeNode root, List<Integer> nodeList){
            Stack<TreeNode> nodeStack = new Stack<TreeNode>();
            TreeNode currentNode=root;
            while(!nodeStack.isEmpty()||currentNode!=null){
                while(currentNode!=null){
                    nodeStack.push(currentNode);
                    currentNode=currentNode.left;
                }
                if(!nodeStack.isEmpty()){
                    currentNode = nodeStack.pop();
                    nodeList.add(currentNode.val);//System.out.println(currentNode);
                    currentNode = currentNode.right;
                }
            }        
        }    
    //     3.后根遍历
        public void afterOrderStack(TreeNode root, List<Integer> nodeList){
            Stack<TreeNode> nodeStack = new Stack<TreeNode>();
            TreeNode currentNode=root,peekNode,popNode,rightNode;
            while(!nodeStack.isEmpty()|| currentNode!=null ){// 第一个while循环
                while(currentNode!=null){// 第二个while循环
                    nodeStack.push(currentNode);
                    currentNode = currentNode.left;
                }
                boolean flag=true;// 右孩子没有访问过的标志
                rightNode=null;
                while(!nodeStack.isEmpty()&&flag) {
                    peekNode = nodeStack.peek();
                    if (peekNode.right==rightNode) {
                        popNode = nodeStack.pop();
                        nodeList.add(popNode.val);//System.out.println(popNode.val);
                        if(nodeStack.isEmpty()){
                            return;
                        }else{
                            rightNode=popNode;
                        }
                    }else{
                        currentNode = peekNode.right;
                        flag=false;
                    }
                }
            }
        }
        public static void main(String[] args){
            
            Solution answer = new Solution();
            TreeNode[] tree = answer.initTree();
            List<Integer> nodeList = new ArrayList<Integer>();
            
            System.out.println("递归算法:");
            System.out.print("	先根遍历	");
            answer.preOrderRecursion(tree[0], nodeList);
            nodeList.forEach(System.out::print);
    //        
            System.out.print("
    	中根遍历	");
            nodeList.clear();
            answer.inOrderRecursion(tree[0], nodeList);
            nodeList.forEach(System.out::print);
    //        
            System.out.print("
    	后根遍历	");
            nodeList.clear();
            answer.afterOrderRecursion(tree[0], nodeList);
            nodeList.forEach(System.out::print);
    //        
            System.out.print("
    非递归算法:");//        
            System.out.print("
    	先根遍历	");
            nodeList.clear();
            answer.preOrderStack(tree[0], nodeList);
            nodeList.forEach(System.out::print);
    
            System.out.print("
    	中根遍历1	");
            nodeList.clear();
            answer.inOrderStackOne(tree[0], nodeList);
            nodeList.forEach(System.out::print);
            
            System.out.print("
    	中根遍历2	");
            nodeList.clear();
            answer.inOrderStackTwo(tree[0], nodeList);
            nodeList.forEach(System.out::print);
    
            System.out.print("
    	后根遍历	");
            nodeList.clear();
            answer.afterOrderStack(tree[0], nodeList);
            nodeList.forEach(System.out::print);
            
        }
    
    }
    递归算法:
        先根遍历    1245891011367
        中根遍历    4285109111637
        后根遍历    4810119526731
    非递归算法:
        先根遍历    1245891011367
        中根遍历1    4285109111637
        中根遍历2    4285109111637
        后根遍历    4810119526731
  • 相关阅读:
    在linux写一个shell脚本用maven git自动更新代码并且打包部署
    maven mvn 命令行 编译打包
    linux修改文件为可执行文件
    shell脚本中根据端口号kill对应的应用进程
    linux如何查看端口被哪个进程占用?
    LINUX中如何查看某个端口是否被占用
    The JAVA_HOME environment variable is not defined correctly的错误
    Linux配置Java环境变量
    requests
    https://www.cnblogs.com/zheting/category/1086753.html
  • 原文地址:https://www.cnblogs.com/sunupo/p/13409400.html
Copyright © 2020-2023  润新知