Java二叉树的四种遍历(递归与非递归)

Java二叉树的四种遍历(递归与非递归)

简介

二叉树是一种常见的数据结构,其遍历方式包括前序遍历、中序遍历、后序遍历和层序遍历。Java中可以使用递归和非递归的方式进行遍历。在该攻略中,我们将详细介绍Java二叉树的四种遍历方式,包括递归和非递归实现,帮助读者提高对Java数据结构的理解。

前序遍历

在前序遍历中,我们先访问二叉树的根节点,然后分别访问左子树和右子树。在Java中,我们可以使用递归和非递归的方式实现前序遍历。

递归实现

public void preOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    System.out.println(root.val);
    preOrderTraversal(root.left);
    preOrderTraversal(root.right);
}

非递归实现

public void preOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while(!stack.isEmpty()){
        TreeNode node = stack.pop();
        System.out.println(node.val);
        if(node.right!=null){
            stack.push(node.right);
        }
        if(node.left!=null){
            stack.push(node.left);
        }
    }
}

中序遍历

在中序遍历中,我们先访问二叉树的左子树,然后访问根节点,最后再访问右子树。同样地,在Java中我们也可以使用递归和非递归的方式实现中序遍历。

递归实现

public void inOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    inOrderTraversal(root.left);
    System.out.println(root.val);
    inOrderTraversal(root.right);
}

非递归实现

public void inOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    Stack<TreeNode> stack = new Stack<>();
    TreeNode node = root;
    while(!stack.isEmpty() || node!=null){
        while(node!=null){
            stack.push(node);
            node = node.left;
        }
        node = stack.pop();
        System.out.println(node.val);
        node = node.right;
    }
}

后序遍历

在后序遍历中,我们先访问二叉树的左子树,然后访问右子树,最后再访问根节点。同样地,在Java中我们也可以使用递归和非递归的方式实现后序遍历。

递归实现

public void postOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    postOrderTraversal(root.left);
    postOrderTraversal(root.right);
    System.out.println(root.val);
}

非递归实现

public void postOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    TreeNode prev = null;
    while(!stack.isEmpty()){
        TreeNode curr = stack.peek();
        if(prev == null || prev.left == curr || prev.right == curr){
            if(curr.left!=null){
                stack.push(curr.left);
            }else if(curr.right!=null){
                stack.push(curr.right);
            }
        }else if(curr.left == prev){
            if(curr.right!=null){
                stack.push(curr.right);
            }
        }else{
            System.out.println(curr.val);
            stack.pop();
        }
        prev = curr;
    } 
}

层序遍历

在层序遍历中,我们按照从上到下、从左到右的顺序访问二叉树的每个节点。同样地,在Java中我们也可以使用队列的非递归方式实现层序遍历。

非递归实现

public void levelOrderTraversal(TreeNode root){
    if(root == null){
        return;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while(!queue.isEmpty()){
        int levelSize = queue.size();
        for(int i=0;i<levelSize;i++){
            TreeNode curr = queue.poll();
            System.out.println(curr.val);
            if(curr.left!=null){
                queue.offer(curr.left);
            }
            if(curr.right!=null){
                queue.offer(curr.right);
            }
        }
    } 
}

示例说明

以下为一个简单的二叉树:

       1
     /   \
    2     3
   / \
  4   5

前序遍历

递归:1 2 4 5 3

非递归:1 2 4 5 3

中序遍历

递归:4 2 5 1 3

非递归:4 2 5 1 3

后序遍历

递归:4 5 2 3 1

非递归:4 5 2 3 1

层序遍历

1 2 3 4 5

以上是Java二叉树的四种遍历方式及其实现。希望能够帮助读者更好地掌握Java的数据结构,提高代码能力。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java二叉树的四种遍历(递归与非递归) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • JS变量及其作用域

    JS变量及其作用域攻略 JavaScript(简称JS)是一种广泛应用于网页开发的脚本语言。在JS中,变量是存储数据的容器,而作用域则决定了变量的可见性和访问范围。本攻略将详细讲解JS变量及其作用域的概念和用法。 变量的声明和赋值 在JS中,变量的声明和赋值是分开进行的。声明变量使用var、let或const关键字,赋值使用赋值操作符=。 // 使用var声…

    other 2023年7月29日
    00
  • MYSQL统计逗号分隔字段元素的个数

    MYSQL统计逗号分隔字段元素的个数是一种统计操作,适用于某些数据表的字段存储了逗号分隔的多个元素,需要统计每个字段包含的元素个数。下面提供了一个完整攻略,步骤如下: 首先,需要使用SUBSTRING_INDEX函数将字段中的逗号分隔的元素分割出来,具体语法如下: SUBSTRING_INDEX(str,delim,count) 其中,str是要分割的字符串…

    other 2023年6月25日
    00
  • ios14.6更新了什么 苹果ios14.6更新内容一览

    iOS 14.6 更新内容一览 苹果于2023年5月发布了 iOS 14.6 更新,该更新带来了一些新功能、改进和修复。以下是 iOS 14.6 更新的详细内容: 1. Apple Music 空间音频(Spatial Audio)支持:iOS 14.6 引入了空间音频功能,使 Apple Music 用户能够享受到更加沉浸式的音频体验。空间音频通过利用头部…

    other 2023年8月3日
    00
  • lambda动态表达式(排序)

    Lambda动态表达式(排序) 在程序开发中,经常需要对集合中的元素进行排序。对于基本类型的数组,可以使用Java中的Arrays.sort()方法进行排序。然而,对于自定义类型的元素,需要实现Comparable接口来实现排序,这会增加代码的复杂性。此时,我们可以使用Lambda动态表达式来实现排序功能。 Lambda表达式是Java8引入的一个重要特性,…

    其他 2023年3月28日
    00
  • SQL字符串以及数字常用操作汇总

    下面是详细的SQL字符串以及数字常用操作汇总: 字符串常用操作 拼接字符串 在SQL中,我们可以使用“+”或concat函数来实现字符串的拼接。下面是两个示例: — 使用"+"实现字符串拼接 SELECT ‘Hello ‘ + ‘world’ AS Result — 使用concat函数实现字符串拼接 SELECT CONCAT(‘H…

    other 2023年6月20日
    00
  • Kotlin类对象class初始化与使用

    Kotlin中的类对象class适用于定义一个类的属性和方法,它们可以方便地被许多代码共用,同时也保证了代码的可维护性和可重用性。下面我们就来详细讲解“Kotlin类对象class初始化与使用”的完整攻略。 类对象class的初始化 类对象class的初始化可以通过构造器进行,也可以在类声明内部通过“init”代码块进行初始化。例如: class Perso…

    other 2023年6月20日
    00
  • mybatis创建一个或多个新用户 insert 字段和表名不确定时动态添加问题

    这个问题涉及到了 Mybatis 的动态 SQL,可以使用 Mybatis 提供的标签进行动态生成 SQL 语句实现。 下面是一个示例的 mapper.xml 文件,用于实现动态插入用户操作: <!–使用了 Mybatis 的动态 SQL 标签 if、foreach–> <insert id="batchInsert&quot…

    other 2023年6月26日
    00
  • C语言实现双向链表

    C语言实现双向链表 简介 双向链表(Doubly Linked List)是一种常用的数据结构,其特点是每个节点既包含指向前驱节点的指针,也包含指向后继节点的指针。相比单向链表,它可以实现双向遍历,删除指定节点时无需遍历整个链表,提高了效率。 本文将详细介绍如何使用C语言实现双向链表。 实现步骤 定义节点结构体 双向链表每个节点包含三个成员变量:数据域、指向…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部