(数据结构)二叉树的前序、中序、后序(用java实现)

他们都是一种深度遍历方式

一:前序遍历        

遍历方式为:根+左子树的前序+右子树的前序

递归方法:利用递归方法,先打印根节点,再递归遍历左子树的前序,最后递归调用有右子树的前序,如果它的根节点为空时,直接返回null

 //前序遍历,法1
    public static void preOrderTraversal(Node root){
        if(root==null){
            return;
        }
        System.out.print(root.value);
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
    }

//前序遍历,法2
public static List<Character> preorder(Node root){
        if(root==null){
            return new ArrayList<>();
        }
        List<Character> list=new ArrayList<>();
        List<Character> leftOrder=preorder(root.left);
        List<Character> rightOrder=preorder(root.right);
        list.add(root.value);
        list.addAll(leftOrder);
        list.addAll(rightOrder);
        return list;
    }

非递归实现:利用栈来实现,利用栈的先进后出实现。

1.当栈不为空或者结点不为空时进行循环,再当结点不为空时,先找到根节点打印出来,再放到栈里面,

2.找它的左节点进行打印并放进栈里面去,直到左节点为空时,跳出结点不为空的循环,弹出栈顶元素,找它的右结点,在进行循环

3.当栈为空时,并且没有接点时,循环结束

//非递归先序遍历
    public static void preorder(Node root){
        Stack<Node> stack=new Stack<>();
        Node cur=root;
        while(!stack.isEmpty()||cur!=null){
            while(cur!=null){
                System.out.print(cur.value);
                stack.push(cur);
                cur=cur.left;
            }
            Node top=stack.pop();
            cur=top.right;
        }
    }

二:中序遍历

遍历方式为:左子树的中序+ 根 + 右子树的中序

递归方法:利用递归方法,先递归遍历左子树的中序,再打印根节点,最后递归调用右子树的中序,如果它的根节点为空时,直接返回null

//中序遍历,法1
 public static void inOrderTraversal(Node root){
        if(root==null){
            return;
        }
        inOrderTraversal(root.left);
        System.out.print(root.value);
        inOrderTraversal(root.right);
    }
//中序遍历,法2
public static List<Character> inorder(Node root){
        if(root==null){
            return new ArrayList<>();
        }
        List<Character> list=new ArrayList<>();
        List<Character> leftOrder=inorder(root.left);
        List<Character> rightOrder=inorder(root.right);
        list.addAll(leftOrder);
        list.add(root.value);
        list.addAll(rightOrder);
        return list;
    }

非递归方法:和前序遍历相似

//非递归中序遍历
    public static void inorder(Node root){
        Stack<Node> stack=new Stack<>();
        Node cur=root;
        while(!stack.isEmpty()||cur!=null){
            while(cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            Node top=stack.pop();
            System.out.print(top.value);
            cur=top.right;
        }
    }

三:后序遍历

遍历方式为:左子树的后序+ 右子树的后序+根

递归方法:利用递归方法,先递归遍历左子树的后序,再递归调用右子树的后序,再打印根节点如果它的根节点为空时,直接返回null

//后序遍历,法1
 public static void postOrderTraversal(Node root){
        if(root==null){
            return;
        }
        postOrderTraversal(root.left);
        postOrderTraversal(root.right);
        System.out.print(root.value);
   }
//后序遍历,法2
public static List<Character> postorder(Node root){
        if(root==null){
            return new ArrayList<>();
        }
        List<Character> list=new ArrayList<>();
        List<Character> leftOrder=postorder(root.left);
        List<Character> rightOrder=postorder(root.right);
        list.addAll(leftOrder);
        list.addAll(rightOrder);
        list.add(root.value);
        return list;
    }

非递归方法:和前序相似,但是要设一个last记录弹出栈的最后一个元素,还要判断结点的右节点是否为空或者已经访问过右节点了,才能将该节点弹出栈并进行打印,可根据代码进行理解

//非递归后序遍历
    public static void postorder(Node root){
        Stack<Node> stack=new Stack<>();
        Node cur=root;
        Node last=null;
        while(!stack.isEmpty()||cur!=null){
            while(cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            Node top=stack.peek();
            if(top.right==null||top.right==last){
                stack.pop();
                System.out.print(top.value);
                last=top;
            }
            else{
                cur=top.right;
            }
        }
    }

最后补充:前、中、后序的遍历方法都很相似,具体也可自己构建一棵树进行遍历,理解方法。

同时:一定要理解递归方法

递推方法的一些诀窍:

1.不要写方法的就做递归展开,站在自己的角度思考,先不用管其他结点

2.找终止条件,在变化的因素中确定,也就是形参

3.找向下的递推公式

4.理解递归方法的调用过程中,会被调用很多次

5.理解调用过程中,局部变量会有多份,只是名字一样

发布了62 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43669007/article/details/100110049