JAVA二叉树的几种遍历(递归,非递归)实现

JAVA二叉树的几种遍历(递归,非递归)实现

二叉树(Binary Tree)是非常重要的数据结构之一,Java中也提供了各种各样的二叉树实现方式。在学习Java的二叉树时,了解二叉树的三种遍历方式非常必要,包括前序遍历、中序遍历和后序遍历。

二叉树遍历

对于二叉树的遍历方式,可以简单地分为两类:深度优先遍历(Depth-First Traversal),广度优先遍历(Breadth-First Traversal)。其中深度遍历可以进一步细分为前序遍历、中序遍历和后序遍历,广度优先遍历又叫做层次遍历。

前序遍历

前序遍历,顾名思义就是指从根节点开始,每次先遍历节点本身,再遍历左右子树。具体实现可参考代码示例1。

// 前序遍历
public static void preOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    System.out.print(root.val + " ");
    preOrderTraversal(root.left);
    preOrderTraversal(root.right);
}

中序遍历

中序遍历,就是指从根节点开始,先遍历左子树,然后遍历根节点本身,最后遍历右子树。具体实现可参考代码示例2。

// 中序遍历
public static void inOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    inOrderTraversal(root.left);
    System.out.print(root.val + " ");
    inOrderTraversal(root.right);
}

后序遍历

后序遍历,就是指从根节点开始,先遍历左右子树,最后遍历根节点本身。具体实现可参考代码示例3。

// 后序遍历
public static void postOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    postOrderTraversal(root.left);
    postOrderTraversal(root.right);
    System.out.print(root.val + " ");
}

非递归遍历

上面的代码是采用递归方式实现的二叉树遍历,但是在实际开发中,递归方式也许并不是最优解。为了避免递归带来的栈溢出等问题,可以采用非递归方式遍历二叉树。具体实现方式可参考代码示例4、5和6。

// 前序遍历非递归实现
public static void preOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.isEmpty()) {
        while (cur != null) {
            System.out.print(cur.val + " ");
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        cur = cur.right;
    }
}

// 中序遍历非递归实现
public static void inOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.isEmpty()) {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        System.out.print(cur.val + " ");
        cur = cur.right;
    }
}

// 后序遍历非递归实现
public static void postOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack1 = new Stack<>();
    Stack<TreeNode> stack2 = new Stack<>();
    TreeNode cur = root;
    stack1.push(cur);
    while (!stack1.isEmpty()) {
        cur = stack1.pop();
        stack2.push(cur);
        if (cur.left != null) {
            stack1.push(cur.left);
        }
        if (cur.right != null) {
            stack1.push(cur.right);
        }
    }
    while (!stack2.isEmpty()) {
        System.out.print(stack2.pop().val + " ");
    }
}

代码示例

代码示例1

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

代码示例2

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

代码示例3

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

代码示例4

public static void preOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.isEmpty()) {
        while (cur != null) {
            System.out.print(cur.val + " ");
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        cur = cur.right;
    }
}

代码示例5

public static void inOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.isEmpty()) {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        System.out.print(cur.val + " ");
        cur = cur.right;
    }
}

代码示例6

public static void postOrderTraversal2(TreeNode root) {
    Stack<TreeNode> stack1 = new Stack<>();
    Stack<TreeNode> stack2 = new Stack<>();
    TreeNode cur = root;
    stack1.push(cur);
    while (!stack1.isEmpty()) {
        cur = stack1.pop();
        stack2.push(cur);
        if (cur.left != null) {
            stack1.push(cur.left);
        }
        if (cur.right != null) {
            stack1.push(cur.right);
        }
    }
    while (!stack2.isEmpty()) {
        System.out.print(stack2.pop().val + " ");
    }
}

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

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

相关文章

  • C语言数据的存储详解

    C语言数据的存储详解 1. 前言 我们在编写C语言程序的时候,不可避免地涉及到内存的管理。C语言程序中的变量、指针、数组等数据都需要存储在内存中。因此,了解C语言中数据存储的机制和原理是非常重要的。 在本篇文章中,我们将详细讲解C语言中数据存储的相关知识,包括变量的声明和定义、变量存储的位置、作用域和生命周期等方面。文章会通过代码示例来帮助大家更好地理解。 …

    other 2023年6月27日
    00
  • 苹果ios7完美越狱一键关机、重启、注销插件推荐 RePower怎么用?

    下面我将详细讲解“苹果ios7完美越狱一键关机、重启、注销插件推荐 RePower怎么用”的完整攻略。 背景介绍 RePower是一款针对越狱设备开发的实用插件,主要提供一键关机、重启、注销等快捷操作,方便用户快速执行关机、重启等功能。 插件安装 要使用RePower插件,首先需要安装Cydia软件(该软件是越狱设备上的一款应用商店),然后在Cydia中搜索…

    other 2023年6月27日
    00
  • html中常用鼠标样式

    以下是“HTML中常用鼠标样式的完整攻略”的详细说明,包括过程中的两个示例说明。 HTML中常用鼠标样式的完整攻略 在HTML中,我们可以使用CSS来设置元素的样式,包括鼠标样式。以下是一份关于HTML中常用鼠标样式的完整攻略。 1. 鼠标样式基础知识 在开始设置鼠标样式之前,我们需要掌握一些基础知识,例如: CSS中的cursor属性,用于设置鼠标样式。 …

    other 2023年5月10日
    00
  • FreeRTOS实时操作系统Cortex-M内核使用注意事项

    FreeRTOS概述 FreeRTOS是一个开源的实时操作系统,广泛应用于单片机、微处理器或DSP等嵌入式系统中,可用于控制器、网络设备、家庭自动化等多种应用场景。FreeRTOS支持多任务处理和多线程处理,能够有效地优化嵌入式系统的资源利用和功耗管理。 Cortex-M内核使用注意事项 在使用FreeRTOS实时操作系统时,需要注意以下几点: 2.1 中断…

    other 2023年6月27日
    00
  • .netef框架的安装、及三种开发模式

    .NET Framework的安装、及三种开发模式 .NET Framework是一个由Microsoft开发的基础架构,用于创建和运行Windows系统上的应用程序,也是创建.NET应用程序的必需组件。本文将介绍.NET Framework的安装方法,并介绍.NET Framework下的三种不同的开发模式。 .NET Framework的安装 .NET …

    其他 2023年3月29日
    00
  • javascript高级程序设计5.pdf

    以下是关于《JavaScript高级程序设计(第5版)》PDF电子书的完整攻略: 什么是《JavaScript高级程序设计(第5版)》PDF电子书 《JavaScript高级程序设计(第5版)》PDF电子书是一本介绍JavaScript语言高级特性和应用的经典教材的电子版,由Nicholas C. Zakas编写。该电子书内容涵盖了JavaScript语言的…

    other 2023年5月7日
    00
  • redis获取自增数

    Redis获取自增数的完整攻略 Redis是一种高性能的键值存储数据库,支持多种数据结构和操作。其中,自增数是一种常见的数据类型可以用于生成唯一的ID或序列号等。本文将提供一份关于Redis获取自增数的完整攻略,包括使用INCR命令和使用Lua脚本两种方法。 使用INCR命令 INCR命令是Redis提供的一种原子性操作,可以对定的键进行自增操作。以下是一个…

    other 2023年5月9日
    00
  • ZooKeeper入门教程一简介与核心概念

    ZooKeeper入门教程一:简介与核心概念 简介 ZooKeeper是一个分布式的解决方案,它可以用来管理和协调分布式应用程序。ZooKeeper可以用于实现诸如分布式锁、服务发现和集群管理等功能。ZooKeeper的设计目标是提供一个高性能、高可靠性、具备严格顺序性、支持分布式部署的专用协调服务。 核心概念 ZNode ZNode是ZooKeeper的数…

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