二叉树的的前中后,层次遍历(java版本)

目录

1.前序遍历(递归实现)

2.中序遍历(递归实现) 

3.后序遍历(递归) 

4.层次遍历 (迭代)


 

1.前序遍历(递归实现)

根>左>右:

优先从根开始遍历,有根则根,无根则左,无左即右,

// 通过构建节点来建立一份二叉树
//           1
//         /  \
//        2    3
//       / \  / \
//      4  5 6   7
//第一遍:1
//第二遍:1,2  由于根'1'已经遍历了,我们开始向左走,进行下一轮的"根>左>右"
//第三遍:1,2,4由于根'2'已经遍历了,我们继续向左走,进行下一轮的"根>左>右"
//第四遍:1,2,4,5  此时,根'4'已经遍历了,而他没有左,我们就返回到4的'父节点'2,注意这个2节点我们已经进行了"根>左"了,我们开始向右遍历的到5
//第五遍:1,2,4,5,3  此时5的左右皆空,返回到2,而2也完成了"根>左>右"继续返回到1,进行1节点的"根>左>右"
//第六遍:1,2,4,5,3,6  同上进行3的"根>左>右,得到6
//第七遍:1,2,4,5,3,6,7  在7的左右皆为空后,循环结束
 public static void preOrderTraversal1(TreeNode node) {
        if (node == null) {
            return;
        }
        System.out.print(node.val + " ");
        preOrderTraversal1(node.left);
        preOrderTraversal1(node.right);

    }

2.中序遍历(递归实现) 

 "左>根>右"

有左左走,无左回头记本身,换向转右,重复以上

//    中序遍历
//    中序遍历的顺序是左子树-> 根节点-> 右子树。
//    递归写法:
    // 通过构建节点来建立一份二叉树
    //           1
    //         /  \
    //        2    3
    //       / \  / \
    //      4  5 6   7
    //第一遍:4  问"根节点"1,你有左吗?答:有,问"根节点"2,你有左吗?答:有,问"根节点"4,你有左吗?答:无,此时以无左可走,即按照"左>根>右"记录下4
    //第二遍:4,2  此时4的左为null,根已经记录,而右亦为空,返回上一级2,2已经进行了"左"现在进行剩下的"根>右"即记录2
    //第三遍:4,2,5  同第一遍,由于5没有左,则返回记录本身,同时5的右为空,返回到根节点1,
    //第四遍:4,2,5,1 节点1的左走完,按照"左>根>右"记录本身1,然后继续向为遍历的">右"遍历
    //第五遍:4,2,5,1,6  3节点有左,即先左走,6无左即记录本身,无右,则返回上一级3,
    //第六遍:4,2,5,1,6,3  懂得都懂,我小3的左都左完了,当然先记录自己本身咯,然后我的右有不为空,当然向右走
    //第七遍:4,2,5,1,6,3,7  这个不说大家应该都明白怎么回事,.....算了还是说一下吧  7无左,即记录本身,无右返回,循环结束
 public static void inOrderTraversal1(TreeNode node) {
            if (node == null) {
                  return;
              }
            inOrderTraversal1(node.left);
            System.out.print(node.val + " ");
            inOrderTraversal1(node.right);
}

3.后序遍历(递归) 

"左>根>右"
// 通过构建节点来建立一份二叉树
//           1
//         /  \
//        2    3
//       / \  / \
//      4  5 6   7
//第一遍:4  有左往左,待到4,无左换右,无右记本身
//第二遍:4,5  退会节点2,走完左边,有右向右,遇无左右的5,即记录
//第三遍:4,5,2  左右走完记本身,同时返回至节点1
//第四遍:4,5,2,6  有右向右,直到6,无左无右,记本身,返回至节点3
//第五遍:4,5,2,6,7  走完左边,有右走右,7无左右记本身,返回至节点3
//第六遍:4,5,2,6,7,3 左右走完记本身,返回至1
//第七遍:4,5,2,6,7,3,1  左右走完,记本身,循环结束
 public static void postOrderTraversal1(TreeNode node) {
    if (node == null) {
        return;
    }
    postOrderTraversal1(node.left);
    postOrderTraversal1(node.right);
    System.out.print(node.val + " ");
}

4.层次遍历 (迭代)

树有多高,就遍历几回
//   迭代写法
// 通过构建节点来建立一份二叉树
//           1
//         /  \
//        2    3
//       / \  / \
//      4  5 6   7
    //第一遍:1  头不为空入队列节点1,根节点1左右不为空,统统录入队列中,此时size长为:2
    //第二遍:1,2,3  打印2,入2的左右节点到队列中,打印3,入3的左右节点到队列中,此时size长为:4
    //第三遍:1,2,3,4,5,6,7  打印 4,5,6,7,由于他们都没有左右节点,此时size长为:0,循环结束
public static void levelOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while(!queue.isEmpty()){
        int size = queue.size();
//        System.out.println("size的大小为:"+size);
        for(int i = 0; i < size; i++){
            TreeNode node = queue.poll();
            System.out.print(node.val + " ");
            if(node.left != null){
                queue.offer(node.left);
            }
            if(node.right != null){
                queue.offer(node.right);
            }
        }
    }
}

完整代码: 

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

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
//    前序遍历
//    前序遍历的顺序是根节点 -> 左子树 -> 右子树。
//    递归写法:
    // 通过构建节点来建立一份二叉树
    //           1
    //         /  \
    //        2    3
    //       / \  / \
    //      4  5 6   7
    //第一遍:1
    //第二遍:1,2  由于根'1'已经遍历了,我们开始向左走,进行下一轮的"根>左>右"
    //第三遍:1,2,4由于根'2'已经遍历了,我们继续向左走,进行下一轮的"根>左>右"
    //第四遍:1,2,4,5  此时,根'4'已经遍历了,而他没有左,我们就返回到4的'父节点'2,注意这个2节点我们已经进行了"根>左"了,我们开始向右遍历的到5
    //第五遍:1,2,4,5,3  此时5的左右皆空,返回到2,而2也完成了"根>左>右"继续返回到1,进行1节点的"根>左>右"
    //第六遍:1,2,4,5,3,6  同上进行3的"根>左>右,得到6
    //第七遍:1,2,4,5,3,6,7  在7的左右皆为空后,循环结束

    public static void preOrderTraversal1(TreeNode node) {
        if (node == null) {
            return;
        }
        System.out.print(node.val + " ");
        preOrderTraversal1(node.left);
        preOrderTraversal1(node.right);

    }
//    迭代写法
    public static void preOrderTraversal2(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                System.out.print(node.val + " ");
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            node = node.right;
        }
    }
//    中序遍历
//    中序遍历的顺序是左子树-> 根节点-> 右子树。
//    递归写法:
    // 通过构建节点来建立一份二叉树
    //           1
    //         /  \
    //        2    3
    //       / \  / \
    //      4  5 6   7
    //第一遍:4  问"根节点"1,你有左吗?答:有,问"根节点"2,你有左吗?答:有,问"根节点"4,你有左吗?答:无,此时以无左可走,即按照"左>根>右"记录下4
    //第二遍:4,2  此时4的左为null,根已经记录,而右亦为空,返回上一级2,2已经进行了"左"现在进行剩下的"根>右"即记录2
    //第三遍:4,2,5  同第一遍,由于5没有左,则返回记录本身,同时5的右为空,返回到根节点1,
    //第四遍:4,2,5,1 节点1的左走完,按照"左>根>右"记录本身1,然后继续向为遍历的">右"遍历
    //第五遍:4,2,5,1,6  3节点有左,即先左走,6无左即记录本身,无右,则返回上一级3,
    //第六遍:4,2,5,1,6,3  懂得都懂,我小3的左都左完了,当然先记录自己本身咯,然后我的右有不为空,当然向右走
    //第七遍:4,2,5,1,6,3,7  这个不说大家应该都明白怎么回事,.....算了还是说一下吧  7无左,即记录本身,无右返回,循环结束


    public static void inOrderTraversal1(TreeNode node) {
            if (node == null) {
                  return;
              }
            inOrderTraversal1(node.left);
            System.out.print(node.val + " ");
            inOrderTraversal1(node.right);
}
//   迭代写法
public static void inOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode node = root;
    while (node != null || !stack.isEmpty()) {
        while (node != null) {
            stack.push(node);
            node = node.left;
        }
        node = stack.pop();
        System.out.print(node.val + " ");
        node = node.right;
    }
}
//  后序遍历
//  后序遍历的顺序是左子树 -> 右子树 -> 根节点。
//  递归写法:
    //    后序遍历
//    后序遍历的顺序是左子树-> 右子树-> 根节点。
//    递归写法:
    // 通过构建节点来建立一份二叉树
    //           1
    //         /  \
    //        2    3
    //       / \  / \
    //      4  5 6   7
    //第一遍:4  有左往左,待到4,无左换右,无右记本身
    //第二遍:4,5  退会节点2,走完左边,有右向右,遇无左右的5,即记录
    //第三遍:4,5,2  左右走完记本身,同时返回至节点1
    //第四遍:4,5,2,6  有右向右,直到6,无左无右,记本身,返回至节点3
    //第五遍:4,5,2,6,7  走完左边,有右走右,7无左右记本身,返回至节点3
    //第六遍:4,5,2,6,7,3 左右走完记本身,返回至1
    //第七遍:4,5,2,6,7,3,1  左右走完,记本身,循环结束


    public static void postOrderTraversal1(TreeNode node) {
    if (node == null) {
        return;
    }
    postOrderTraversal1(node.left);
    postOrderTraversal1(node.right);
    System.out.print(node.val + " ");
}
//  迭代写法
public static void postOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    //添加一个指向上一个访问的节点的指针,用于判断是否打印父节点
    TreeNode prev = null;
    TreeNode node = root;
    while(node != null || !stack.isEmpty()){
        while(node != null){
            stack.push(node);
            node = node.left;
        }
        node = stack.peek();
        //右子节点为空或者右子节点已经被访问过了,说明当前节点可以被访问了
        if(node.right == null || node.right == prev){
            System.out.print(node.val + " ");
            stack.pop();
            prev = node; //更新prev指针,避免重复访问右子节点
            node = null;
        } else {
            node = node.right;
        }
    }
}
//  层次遍历
//  层次遍历是按层次,从上到下,从左到右遍历每个节点。
//  递归写法:
//  由于层次遍历需要记录当前层次的节点值,故没有递归写法。
//迭代写法:
//    后序遍历
//    后序遍历的顺序是;从头节点开始,至树的高度
//   迭代写法
// 通过构建节点来建立一份二叉树
//           1
//         /  \
//        2    3
//       / \  / \
//      4  5 6   7
    //第一遍:1  头不为空入队列节点1,根节点1左右不为空,统统录入队列中,此时size长为:2
    //第二遍:1,2,3  打印2,入2的左右节点到队列中,打印3,入3的左右节点到队列中,此时size长为:4
    //第三遍:1,2,3,4,5,6,7  打印 4,5,6,7,由于他们都没有左右节点,此时size长为:0,循环结束

public static void levelOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while(!queue.isEmpty()){
        int size = queue.size();
//        System.out.println("size的大小为:"+size);
        for(int i = 0; i < size; i++){
            TreeNode node = queue.poll();
            System.out.print(node.val + " ");
            if(node.left != null){
                queue.offer(node.left);
            }
            if(node.right != null){
                queue.offer(node.right);
            }
        }
    }
}
    public static void main(String[] args) {
        // 通过构建节点来建立一份二叉树
        //           1
        //         /  \
        //        2    3
        //       / \  / \
        //      4  5 6   7
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);
        System.out.print("前序遍历递归写法: ");
        preOrderTraversal1(root);
        System.out.println();
        System.out.print("前序遍历迭代写法: ");
        preOrderTraversal2(root);
        System.out.println();
        System.out.print("中序遍历递归写法: ");
        inOrderTraversal1(root);
        System.out.println();
        System.out.print("中序遍历迭代写法: ");
        inOrderTraversal2(root);
        System.out.println();
        System.out.print("后序遍历递归写法: ");
        postOrderTraversal1(root);
        System.out.println();
        System.out.print("后序遍历迭代写法: ");
        postOrderTraversal2(root);
        System.out.println();
        System.out.print("层次遍历递归写法: ");
        levelOrderTraversal(root);





    }
}










 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值