java二叉树的非递归遍历

下面我详细讲解一下Java二叉树的非递归遍历的完整攻略。

1. 什么是二叉树?

二叉树(Binary Tree)是一种树型的数据结构,它的每个节点最多只有两个子节点,分别称为左子节点和右子节点。

2. 如何遍历二叉树?

二叉树的遍历有三种方式:前序遍历、中序遍历和后序遍历。

  • 前序遍历:先访问根节点,再遍历左子树和右子树。
  • 中序遍历:先遍历左子树,再访问根节点,最后遍历右子树。
  • 后序遍历:先遍历左子树,再遍历右子树,最后访问根节点。

3. 非递归遍历的思路

非递归遍历深度优先二叉树有两种经典的做法,一种是使用栈来模拟递归过程;另一种是使用线索二叉树的方式来遍历。下面分别进行讲解。

3.1 使用栈来模拟递归过程

采用栈来模拟递归遍历,算法思路如下:

  1. 如果当前节点不为空,入栈并将当前节点更新为左子节点,再次判断是否为空。
  2. 如果当前节点为空且栈非空,则出栈,并访问出栈节点的右子节点。
  3. 重复执行1、2步,直到栈为空。

以下为Java代码示例,实现二叉树的前序、中序、后序非递归遍历。

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class BinaryTreeTraversal {
    // 前序遍历
    public static 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.print(node.val + " ");
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
    }

    // 中序遍历
    public static void inOrderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        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 postOrderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(root);
        while (!stack1.isEmpty()) {
            TreeNode node = stack1.pop();
            stack2.push(node);
            if (node.left != null) {
                stack1.push(node.left);
            }
            if (node.right != null) {
                stack1.push(node.right);
            }
        }
        while (!stack2.isEmpty()) {
            System.out.print(stack2.pop().val + " ");
        }
    }
}

3.2 使用线索二叉树的方式来遍历

线索二叉树是对二叉树进行了改进,把有右孩子的节点的右孩子指针变成指向后继节点,有左孩子的节点的左孩子指针变成指向前驱节点。这样就可以避免使用栈来模拟递归,从而实现二叉树的非递归遍历。

以下是Java代码示例,实现二叉树的中序非递归遍历。

public class ThreadedBinaryTreeTraversal {
    static class ThreadedNode {
        int val;
        ThreadedNode left;
        ThreadedNode right;
        boolean isLeftThread;
        boolean isRightThread;

        ThreadedNode(int val) {
            this.val = val;
            this.isLeftThread = false;
            this.isRightThread = false;
        }
    }

    static ThreadedNode pre = null;

    // 构建线索二叉树
    public static void inOrderThread(ThreadedNode node) {
        if (node == null) {
            return;
        }
        inOrderThread(node.left);
        if (node.left == null) {
            node.left = pre;
            node.isLeftThread = true;
        }
        if (pre != null && pre.right == null) {
            pre.right = node;
            pre.isRightThread = true;
        }
        pre = node;
        inOrderThread(node.right);
    }

    // 中序遍历
    public static void inOrderTraversal(ThreadedNode root) {
        ThreadedNode node = root;
        while (node != null) {
            while (!node.isLeftThread && node.left != null) {
                node = node.left;
            }
            System.out.print(node.val + " ");
            while (node.isRightThread) {
                node = node.right;
                System.out.print(node.val + " ");
            }
            node = node.right;
        }
    }

    public static void main(String[] args) {
        ThreadedNode root = new ThreadedNode(1);
        root.left = new ThreadedNode(2);
        root.right = new ThreadedNode(3);
        root.left.left = new ThreadedNode(4);
        root.left.right = new ThreadedNode(5);
        root.right.left = new ThreadedNode(6);
        root.right.right = new ThreadedNode(7);

        inOrderThread(root);
        inOrderTraversal(root);
    }
}

4. 总结

Java二叉树的非递归遍历,可以使用栈来模拟递归过程,也可以采用线索二叉树的方式来实现,两种方式相较于递归遍历,更节省空间,提高效率。其中,栈模拟递归方式适用于前序、中序和后序遍历,线索二叉树方式适用于中序遍历。

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

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

相关文章

  • 怎么下载网页视频

    如何下载网页视频? 如果您想要下载网页视频并保存到您的设备上,下面是一些步骤和示例,以帮助您完成这项任务。 步骤1:找到要下载的网页视频 首先,您需要找到要下载的网页视频,可以在视频页面上查找网址或复制视频网址。 步骤2:安装视频下载工具 有许多视频下载工具可供选择,常见的工具包括ffmpeg、youtube-dl、VLC、Video DownloadHel…

    其他 2023年4月16日
    00
  • Android中你可能不知道的Fragment妙用

    下面是“Android中你可能不知道的Fragment妙用”的完整攻略。 简介 Fragment 是 Android 开发中非常重要的一个概念,它可以让我们开发出更加灵活、复杂的界面。但是除了 Fragment 常见的使用场景,还有许多我们可能不太熟悉的用法,这篇文章就来介绍一下。 Fragment 的用途 多面板界面支持 多语言支持 直接管理 Fragme…

    other 2023年6月26日
    00
  • Entity Framework表拆分为多个实体

    对于Entity Framework中表拆分为多个实体,我们可以采用以下的完整攻略来实现。 第一步:创建数据模型 首先,我们需要在Entity Framework中创建数据模型。可以通过以下步骤来实现: 在Visual Studio中创建一个新的空项目。 在解决方案资源管理器中,右键单击项目,选择“添加”->“新建项”。 在“添加新项”对话框中选择“A…

    other 2023年6月26日
    00
  • jsonpath中的表达式

    jsonpath中的表达式 什么是jsonpath Jsonpath是一个类似于XPath的json对象查找工具,用于查找json数据中的数据。它是一个用于从json中提取数据的工具,可以用来在json数据中定位和操作值,并且比传统的for循环和条件判断更加简单和高效。 jsonpath表达式语法 jsonpath是用于选择从json数据中提取信息的嵌套路径…

    其他 2023年3月29日
    00
  • VC++中进程与多进程管理的方法详解

    针对“VC++中进程与多进程管理的方法详解”的完整攻略,我给出以下详细内容: VC++中进程与多进程管理的方法详解 1. 进程和多进程的概念 进程是一个正在运行的程序的实例,它包含了程序代码和当前正在执行的程序状态。每一个进程都有一个唯一的进程标识符(PID)来区分自己和其他进程。在Windows系统中,每个进程有自己的地址空间、栈、寄存器和堆。 多进程是指…

    other 2023年6月25日
    00
  • 为Android Studio编写自定义Gradle插件的教程

    自定义Gradle插件可以让我们在构建过程中实现更多的定制化和灵活性。本文将讲解如何为Android Studio编写自定义Gradle插件的教程。本文将分为以下几个章节: 前置知识要求 创建Gradle插件项目 编写Gradle插件代码 发布和使用自定义Gradle插件 1. 前置知识要求 在开始撰写自定义的Gradle插件之前,需要掌握以下几个方面的知识…

    other 2023年6月25日
    00
  • u盘无法拷贝大于4g的文件解决办法汇总

    U盘无法拷贝大于4G的文件解决办法汇总 若你经常使用U盘传输数据,可能会遇到一个比较常见的问题 – 当你尝试拷贝一个大于4G的文件到U盘时却发现失败了。这是因为大多数U盘都使用FAT32格式,而这个格式对单个文件的大小有4GB的限制。那怎么才能处理这个问题呢?本文将为你提供几种解决办法。 方法一:将U盘格式化为NTFS 新一代的Windows系统(如Wind…

    其他 2023年3月28日
    00
  • div的显示隐藏方法汇总

    当然,我很乐意为您提供有关“div的显示隐藏方法汇总”的完整攻略。以下是详细的步骤和两个示例: 1. div是什么? div是HTML中的一个标签,用于定义文档中的一个区域。div标签可以用于布局和样式控制,可以包含其他HTML元素。 以下是div标签的基本语法: <div>content</div> 在这个示例中,我们使用div标签…

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