Java常见算法(四)【二叉树遍历:递归、迭代(模拟递归)】

8 篇文章 2 订阅

二叉树遍历

https://www.bilibili.com/video/BV1Jv411A7Ty?p=22
在这里插入图片描述

1、前序遍历-递归

https://www.bilibili.com/video/BV1Jv411A7Ty?p=23

前序、中序、后续遍历其实就是一直打印栈顶,但是打印的时机有所不同;

前序遍历是第一次成为栈顶就打印。
在这里插入图片描述
在这里插入图片描述

 //1、前序-递归
    public static void preorder(TreeNode root){
        if(root==null){
            return;
        }
        System.out.println(root.val);//(第一次成为栈顶才打印)
        preorder(root.left);
        preorder(root.right);
    }

结果:

1
2
4
5
6
7
3

2、中序遍历-递归

https://www.bilibili.com/video/BV1Jv411A7Ty?p=24

前序、中序、后续遍历其实就是一直打印栈顶,但是打印的时机有所不同;

中序遍历是第二次成为栈顶才打印。
在这里插入图片描述
在这里插入图片描述

 //1、中序-递归(第二次成为栈顶才打印)
    public static void preorder1(TreeNode root){
        if(root==null){
            return;
        }
        
        preorder1(root.left);
        System.out.println(root.val);//(第二次成为栈顶时进行打印)
        preorder1(root.right);
    }

结果:

4
2
6
5
7
1
3

3、后序遍历-递归

https://www.bilibili.com/video/BV1Jv411A7Ty?p=25

前序、中序、后续遍历其实就是一直打印栈顶,但是打印的时机有所不同;

后序遍历是第三次成为栈顶才打印。
在这里插入图片描述
在这里插入图片描述

 //1、后序-递归(第三次成为栈顶才打印)
    public static void preorder2(TreeNode root){
        if(root==null){
            return;
        }
        preorder2(root.left);
        preorder2(root.right);
        System.out.println(root.val);//(第三次成为栈顶时进行打印)
    }

结果:

2
4
5
6
7
3
1

4、层序遍历-递归

在这里插入图片描述

//4、层序遍历
    public static void levelOrder(TreeNode root,int i, ArrayList list){
        if(root==null){
            return;
        }
        //为了防止数组越界,需要进行数组容量填充
        int lenght=list.size();
        if(lenght<=i){
            for (int j=0;j<=i-lenght;j++){
                list.add(lenght+j,null);
            }
        }
        list.set(i,root.val);
        levelOrder(root.left,2*i,list);
        levelOrder(root.right,2*i+1,list);
    }

前序、中序、后续、层序 递归遍历实验源码

package com.example.rabbitmq;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.LinkedList;
import java.util.Queue;

@SpringBootTest
/*
    二叉树遍历
 */
class SuanfaApplicationTests17 {

    //定义一个二叉树
    static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public int deep;//深度
        public TreeNode(){}
        public TreeNode(int val){this.val=val;}
        public TreeNode(int val,TreeNode left,TreeNode right){
            this.val=val;
            this.left=left;
            this.right=right;
        }
    }

    //1、前序-递归
    public static void preorder(TreeNode root){
        if(root==null){
            return;
        }
        System.out.println(root.val);//(第一次成为栈顶才打印)
        preorder(root.left);
        preorder(root.right);
    }

    //2、中序-递归
    public static void preorder1(TreeNode root){
        if(root==null){
            return;
        }
        preorder1(root.left);
        System.out.println(root.val);//(第二次成为栈顶时进行打印)
        preorder1(root.right);
    }

    //3、后序-递归
    public static void preorder2(TreeNode root){
        if(root==null){
            return;
        }
        preorder(root.left);
        preorder(root.right);
        System.out.println(root.val);//(第三次成为栈顶时进行打印)
    }

 //4、层序遍历
    public static void levelOrder(TreeNode root,int i, ArrayList list){
        if(root==null){
            return;
        }
        //为了防止数组越界,需要进行数组容量填充
        int lenght=list.size();
        if(lenght<=i){
            for (int j=0;j<=i-lenght;j++){
                list.add(lenght+j,null);
            }
        }
        list.set(i,root.val);
        levelOrder(root.left,2*i,list);
        levelOrder(root.right,2*i+1,list);
    }

    @Test
    public void sf0(){
        //构造一个二叉树
        TreeNode node7=new TreeNode(7,null,null);
        TreeNode node6=new TreeNode(6,null,null);
        TreeNode node5=new TreeNode(5,node6,node7);
        TreeNode node4=new TreeNode(4,null,null);
        TreeNode node3=new TreeNode(3,null,null);
        TreeNode node2=new TreeNode(2,node4,node5);
        TreeNode node1=new TreeNode(1,node2,node3);

        System.out.println("-------前序------");
        preorder(node1);
        System.out.println("-------中序------");
        preorder1(node1);
        System.out.println("-------后序------");
        preorder2(node1);
              System.out.println("-------层序遍历------");
        ArrayList list = new ArrayList();
        levelOrder(node1,1,list);
        Object collect = list.stream().filter(item -> item != null).collect(Collectors.toList());
        System.out.println(collect.toString());
    }

}

结果:

-------前序------
1
2
4
5
6
7
3
-------中序------
4
2
6
5
7
1
3
-------后序------
2
4
5
6
7
3
1
-------层序遍历------
[1, 2, 3, 4, 5, 6, 7]

5、前序遍历-迭代(模拟递归遍历)

   //1、前序-迭代:根   左  右
    public static void preorder(TreeNode root){
        if(root!=null){
            Stack<TreeNode> stack=new Stack<TreeNode>();
            stack.add(root);
            while (!stack.isEmpty()){
                root=stack.pop();
                if(root!=null){
                    System.out.println(root.val);
                    stack.push(root.right);
                    stack.push(root.left);
                }
            }
        }
    }

6、中序遍历-迭代(模拟递归遍历)

//2、中序-迭代:左  根  右
    public static void preorder1(TreeNode root){
        if(root!=null){
            Stack<TreeNode> stack=new Stack<TreeNode>();
            while (!stack.isEmpty()||root!=null){
                if(root!=null){
                    stack.push(root);
                    root=root.left;
                }else{
                    root=stack.pop();
                    System.out.println(root.val);
                    root=root.right;
                }
            }
        }
    }

7、后序遍历-迭代(模拟递归遍历)

//3、后序-迭代:左   右  根
    public static void preorder2(TreeNode root){
        if(root!=null){
            Stack<TreeNode> stack=new Stack<TreeNode>();
            TreeNode prev=null;//记录位置用
            while (!stack.isEmpty()||root!=null){
                if(root!=null){
                    stack.push(root);
                    root=root.left;
                }
                root=stack.pop();
                if(root.right==null||root.right==prev){
                    System.out.println(root.val);
                    prev=root;
                    root=null;
                }else {
                    stack.push(root);
                    root=root.right;
                }
            }
        }
    }

8、层序遍历-迭代(利用队列先进先出特点:从上到下、从左到右)

 //4、层序-迭代(利用队列先进先出特点):从上到下、从左到右
    public static void preorder3(TreeNode root){
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);//入队
        while(!q.isEmpty()){
            TreeNode node = q.poll();//出队
            if(node!=null){
                System.out.println(node.val);
                q.add(node.left);
                q.add(node.right);
            }
        }
    }

前序、中序、后续、层序,遍历(迭代)实验源码:

package com.example.rabbitmq;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.stream.Collectors;

@SpringBootTest
/*
    二叉树遍历-迭代
 */
class SuanfaApplicationTests18 {

    //定义一个二叉树
    static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public int deep;//深度
        public TreeNode(){}
        public TreeNode(int val){this.val=val;}
        public TreeNode(int val,TreeNode left,TreeNode right){
            this.val=val;
            this.left=left;
            this.right=right;
        }
    }

    //1、前序-迭代:根   左  右
    public static void preorder(TreeNode root){
        if(root!=null){
            Stack<TreeNode> stack=new Stack<TreeNode>();
            stack.add(root);
            while (!stack.isEmpty()){
                root=stack.pop();
                if(root!=null){
                    System.out.println(root.val);
                    stack.push(root.right);
                    stack.push(root.left);
                }
            }
        }
    }

    //2、中序-迭代:左  根  右
    public static void preorder1(TreeNode root){
        if(root!=null){
            Stack<TreeNode> stack=new Stack<TreeNode>();
            while (!stack.isEmpty()||root!=null){
                if(root!=null){
                    stack.push(root);
                    root=root.left;
                }else{
                    root=stack.pop();
                    System.out.println(root.val);
                    root=root.right;
                }
            }
        }
    }

    //3、后序-迭代:左   右  根
    public static void preorder2(TreeNode root){
        if(root!=null){
            Stack<TreeNode> stack=new Stack<TreeNode>();
            TreeNode prev=null;//记录位置用
            while (!stack.isEmpty()||root!=null){
                 while (root!=null){
                    stack.push(root);
                    root=root.left;
                }
                root=stack.pop();
                if(root.right==null||root.right==prev){
                    System.out.println(root.val);
                    prev=root;
                    root=null;
                }else {
                    stack.push(root);
                    root=root.right;
                }
            }
        }
    }

    //4、层序-迭代(利用队列先进先出特点):从上到下、从左到右
    public static void preorder3(TreeNode root){
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);//入队
        while(!q.isEmpty()){
            TreeNode node = q.poll();//出队
            if(node!=null){
                System.out.println(node.val);
                q.add(node.left);
                q.add(node.right);
            }
        }
    }

    @Test
    public void sf0(){
        //构造一个二叉树
        TreeNode node7=new TreeNode(7,null,null);
        TreeNode node6=new TreeNode(6,null,null);
        TreeNode node5=new TreeNode(5,node6,node7);
        TreeNode node4=new TreeNode(4,null,null);
        TreeNode node3=new TreeNode(3,null,null);
        TreeNode node2=new TreeNode(2,node4,node5);
        TreeNode node1=new TreeNode(1,node2,node3);

        System.out.println("-------前序遍历-迭代(模拟递归)------");
        preorder(node1);

        System.out.println("-------中序遍历-迭代(模拟递归)------");
        preorder1(node1);

        System.out.println("-------后序遍历-迭代(模拟递归)------");
        preorder2(node1);

        System.out.println("-------层序遍历-迭代(模拟递归)------");
        preorder3(node1);
    }

}

结果:

-------前序遍历-迭代(模拟递归)------
1
2
4
5
6
7
3
-------中序遍历-迭代(模拟递归)------
4
2
6
5
7
1
3
-------后序遍历-迭代(模拟递归)------
4
6
7
5
2
3
1
-------层序遍历-迭代(模拟递归)------
1
2
3
4
5
6
7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的小蜗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值