Java创建二叉树及其遍历的递归和非递归实现
来源:互联网 发布:手机游戏网络加速器 编辑:程序博客网 时间:2024/05/29 08:36
紧接上一篇,网上搜索了Java实现二叉树的方法及二叉树的遍历方法,参考:http://blog.csdn.net/skylinesky/article/details/6611442
学习和调试后代码如下:
测试数据(#表示节点为空):
所建立二叉树如下:
代码如下:
// 树的节点public class TreeNode {private TreeNode left;private TreeNode right;private String val;public TreeNode(){}public TreeNode(String val) {super();this.val = val;}public TreeNode(TreeNode left, TreeNode right, String val) {super();this.left = left;this.right = right;this.val = val;}public TreeNode getLeft() {return left;}public void setLeft(TreeNode left) {this.left = left;}public TreeNode getRight() {return right;}public void setRight(TreeNode right) {this.right = right;}public String getVal() {return val;}public void setVal(String val) {this.val = val;}}
创建二叉树及其中序、先序、后序遍历的递归和非递归实现方法、层次遍历
import java.io.File;import java.io.FileNotFoundException;import java.util.Queue;import java.util.Scanner;import java.util.Stack;import java.util.concurrent.LinkedBlockingQueue;public class Tree {private TreeNode root;public Tree() {}public Tree(TreeNode root) {this.root = root;}// 创建二叉树public void buildTree() {Scanner scn = null;try {scn = new Scanner(new File("D:\\test\\input.txt"));} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}root = createTree(root, scn);}// 先序遍历创建二叉树private TreeNode createTree(TreeNode root, Scanner scn) {String temp = scn.next();if (temp.trim().equals("#")) {return null;} else {root = new TreeNode(temp);root.setLeft(createTree(root.getLeft(), scn));root.setRight(createTree(root.getRight(), scn));return root;}}// 中序遍历(递归) —— 左、根、右public void inOrderTraverse() {inOrderTraverse(root);}public void inOrderTraverse(TreeNode root) {if (root != null) {inOrderTraverse(root.getLeft());System.out.print(root.getVal() + " ");inOrderTraverse(root.getRight());}}// 中序遍历(非递归)public void nrInorderTraverse() {Stack<TreeNode> stack = new Stack<TreeNode>();TreeNode node = root;while (node != null || !stack.isEmpty()) { // 右子树不为空,或者栈不为空while (node != null) { // 从根或右子树开始,把所有的左孩子的左孩子全部入栈,直到找到最里面的左孩子stack.push(node);node = node.getLeft();}node = stack.pop(); // 出栈左孩子或者根节点System.out.print(node.getVal() + " ");node = node.getRight(); // 遍历之后,处理右子树内容。循环遍历右子树的左孩子等等}}// 先序遍历(递归) —— 根、左、右public void preOrderTraverse() {preOrderTraverse(root);}public void preOrderTraverse(TreeNode root) {if (root != null) {System.out.print(root.getVal() + " ");preOrderTraverse(root.getLeft());preOrderTraverse(root.getRight());}}// 先序遍历(非递归)public void nrPreOrderTraverse() {Stack<TreeNode> stack = new Stack<TreeNode>();TreeNode node = root;while (node != null || !stack.isEmpty()) { // 右子树不为空,或者栈不为空while (node != null) {System.out.print(node.getVal() + " "); // 遍历根节点和左子树的一系列的“根”,并将它们全部入栈stack.push(node);node = node.getLeft();}node = stack.pop(); // 弹出此时最里面的左子树根节点,判断其右子树情况node = node.getRight(); // 处理右子树情况}}// 后序遍历(递归) —— 左、右、根public void postOrderTraverse() {postOrderTraverse(root);}public void postOrderTraverse(TreeNode root) {if (root != null) {postOrderTraverse(root.getLeft());postOrderTraverse(root.getRight());System.out.print(root.getVal() + " ");}}// 后序遍历(非递归)public void nrPostOrderTraverse() {Stack<TreeNode> stack = new Stack<TreeNode>();TreeNode node = root;TreeNode preNode = null; // 表示最近一次访问的节点while (node != null || !stack.isEmpty()) { // 右子树不为空,或者栈不为空(其子树已经处理过)while (node != null) { // 将根节点和左子树的根节点入栈,直到左子树为空stack.push(node);node = node.getLeft();}node = stack.peek(); // stack.peek()查找栈顶对象,但不移除它 查看栈顶元素if (node.getRight() == null || node.getRight() == preNode) { // 该节点的右子树为空,或者其右子树已经被访问过System.out.print(node.getVal() + " "); // 访问该节点node = stack.pop();preNode = node;node = null; // 将node置为空,用于判断栈中的下一元素} else {node = node.getRight();}}}// 按层次遍历public void levelTraverse() {levelTraverse(root);}public void levelTraverse(TreeNode root) {Queue<TreeNode> queue = new LinkedBlockingQueue<TreeNode>(); // Queue为接口queue.add(root);while (!queue.isEmpty()) {TreeNode temp = queue.poll(); // queue.poll()获取并移除队头元素if (temp != null) {System.out.print(temp.getVal() + " ");if (temp.getLeft() != null) {queue.add(temp.getLeft());}if (temp.getRight() != null) {queue.add(temp.getRight());}}}}}
注意:各种非递归方式的实现是借助栈或者队列来实现的,利用了它们的进出的特点,关于非递归的实现,可以从分析具体的遍历来得到思路。
中序遍历和先序遍历的非递归方式有点类似,不同的地方在于,什么时候打印“根节点”。
后序遍历,需要好好理解遍历节点操作(使用stack.peek方法,还有参数preNode)
测试代码:
public class BinaryTreeTest {public static void main(String[] args) {Tree tree = new Tree();tree.buildTree();System.out.println("中序遍历");tree.inOrderTraverse();System.out.println("\n中序遍历(非递归)");tree.nrInorderTraverse();System.out.println("\n先序遍历");tree.preOrderTraverse();System.out.println("\n先序遍历(非递归)");tree.nrPreOrderTraverse();System.out.println("\n后序遍历");tree.postOrderTraverse();System.out.println("\n后序遍历(非递归)");tree.nrPostOrderTraverse();System.out.println("\n层次遍历");tree.levelTraverse();}}
代码运行结果:
0 0
- Java创建二叉树及其遍历的递归和非递归实现
- Java实现二叉树的创建、递归/非递归遍历
- 二叉树创建、遍历的递归和非递归实现
- 二叉树及其遍历(递归和非递归实现)
- java 二叉树的递归遍历和非递归遍历
- 二叉树的创建及递归和非递归遍历
- 二叉树的创建,递归和非递归遍历
- 二叉树的创建和递归与非递归遍历
- Java实现二叉树的递归与非递归遍历
- Java实现二叉树的递归、非递归遍历
- 二叉树的遍历:递归和非递归实现
- 二叉树遍历的递归和非递归实现
- 二叉树遍历输出的递归和非递归实现
- 二叉树的遍历(非递归和递归实现)
- 二叉树的前中后序遍历-递归和非递归实现
- 二叉树遍历的递归和非递归实现
- 二叉树的遍历实现(递归和非递归)
- 递归和非递归实现二叉树的后续遍历
- 内联函数(转载)
- 诸葛:三个原因,毁了数据分析态度
- BoW图像检索Python实战
- Activemq配置——Jaas方式配置用户登录验证
- 修改Tomcat默认编码
- Java创建二叉树及其遍历的递归和非递归实现
- android bluedroid调试
- UVA 11054 - Wine trading in Gergovia
- Repo 下载路径
- Flume NG源码分析(三)使用Event接口表示数据流
- Qt开发ActiveX及环境搭建
- C++中的单例模式
- Windows Server2012 虚拟机复制及故障转移(Part4)
- Ubuntu系统如何安装双网卡及更改网卡名称(eth0改为eth1)