一个程序理解java二叉树-创建、递归非递归便利、获取路径
2017-08-02 16:54
639 查看
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Stack; public class TreeNodeExample { private int[] array = { 1, 2, 3, 4, 5, 6}; private static List<Node> nodeList = null; /** * 内部类:节点 * * @author ocaicai@yeah.net @date: 2011-5-17 * */ private static class Node { Node leftChild; Node rightChild; int data; Node(int newData) { leftChild = null; rightChild = null; data = newData; } } public void createBinTree() { nodeList = new LinkedList<Node>(); // 将一个数组的值依次转换为Node节点 for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) { nodeList.add(new Node(array[nodeIndex])); } // 对前lastParentIndex-1个父节点按照父节点与孩子节点的数字关系建立二叉树 for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) { // 左孩子 nodeList.get(parentIndex).leftChild = nodeList .get(parentIndex * 2 + 1); // 右孩子 nodeList.get(parentIndex).rightChild = nodeList .get(parentIndex * 2 + 2); } // 最后一个父节点:因为最后一个父节点可能没有右孩子,所以单独拿出来处理 int lastParentIndex = array.length / 2 - 1; // 左孩子 nodeList.get(lastParentIndex).leftChild = nodeList .get(lastParentIndex * 2 + 1); // 右孩子,如果数组的长度为奇数才建立右孩子 if (array.length % 2 == 1) { nodeList.get(lastParentIndex).rightChild = nodeList .get(lastParentIndex * 2 + 2); } } /** * 先序遍历 * * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 * * @param node * 遍历的节点 */ public static void preOrderTraverse(Node node) { if (node == null) return; System.out.print(node.data + " "); preOrderTraverse(node.leftChild); preOrderTraverse(node.rightChild); } /** * 中序遍历 * * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 * * @param node * 遍历的节点 */ public static void inOrderTraverse(Node node) { if (node == null) return; inOrderTraverse(node.leftChild); System.out.print(node.data + " "); inOrderTraverse(node.rightChild); } /** * 后序遍历 * * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 * * @param node * 遍历的节点 */ public static void postOrderTraverse(Node node) { if (node == null) return; postOrderTraverse(node.leftChild); postOrderTraverse(node.rightChild); System.out.print(node.data + " "); } /** 非递归实现前序遍历 */ protected static void iterativePreorder(Node p) { Stack<Node> stack = new Stack<Node>(); if (p != null) { stack.push(p); while (!stack.empty()) { p = stack.pop(); visit(p); if (p.rightChild != null) stack.push(p.rightChild); if (p.leftChild != null) stack.push(p.leftChild); } } } /** 非递归实现后序遍历 */ protected static void iterativePostorder(Node p) { Node q = p; Stack<Node> stack = new Stack<Node>(); while (p != null) { // 左子树入栈 for (; p.leftChild != null; p = p.leftChild) stack.push(p); // 当前节点无右子或右子已经输出 while (p != null && (p.rightChild == null || p.rightChild == q)) { visit(p); q = p;// 记录上一个已输出节点 if (stack.empty()) return; p = stack.pop(); } // 处理右子 stack.push(p); p = p.rightChild; } } /** 非递归实现中序遍历 */ protected static void iterativeInorder(Node p) { Stack<Node> stack = new Stack<Node>(); while (p != null) { while (p != null) { if (p.rightChild != null) stack.push(p.rightChild);// 当前节点右子入栈 stack.push(p);// 当前节点入栈 p = p.leftChild; } p = stack.pop(); while (!stack.empty() && p.rightChild == null) {//没有右子树,直接出栈 visit(p); p = stack.pop(); } visit(p);////有右子树,循环 if (!stack.empty()) p = stack.pop(); else p = null; } } /** 访问节点 */ public static void visit(Node p) { System.out.print(p.data + " "); } /************************************************************************/ public static List<String> binaryTreePaths(Node root) { List<String> answer = new ArrayList<String>(); if (root != null) searchBT(root, "", answer); return answer; } private static void searchBT(Node root, String path, List<String> answer) { if (root.leftChild == null && root.rightChild == null) answer.add(path + root.data); if (root.leftChild != null) searchBT(root.leftChild, path + root.data + "-", answer); if (root.rightChild != null) searchBT(root.rightChild, path + root.data + "-", answer); } /************************************************************************/ public static void main(String[] args) { TreeNodeExample binTree = new TreeNodeExample(); binTree.createBinTree(); // nodeList中第0个索引处的值即为根节点 Node root = nodeList.get(0); System.out.println("先序遍历:"); System.out.print("递归实现-->"); preOrderTraverse(root); System.out.println(); System.out.print("非递归实现-->"); iterativePreorder(root); System.out.println(); System.out.println("中序遍历:"); System.out.print("递归实现-->"); inOrderTraverse(root); System.out.println(); System.out.print("非递归实现-->"); iterativeInorder(root); System.out.println(); System.out.println("后序遍历:"); System.out.print("递归实现-->"); postOrderTraverse(root); System.out.println(); System.out.print("非递归实现-->"); iterativePostorder(root); System.out.println(); //获取二叉树上的所有路径 List<String> result = binaryTreePaths(root); System.out.println("二叉树上的所有路径"); for(String path: result){ System.err.println(path); } } }
相关文章推荐
- java二叉树漫谈--二叉树的递归便利和路径
- java 递归获取一个目录下的所有文件路径
- java 用递归获取一个目录下的所有文件路径的小例子
- 【理解】一个利用递归打印对象路径下所有文件的小程序
- java 递归获取一个目录下的所有文件路径
- java 程序中获取session/request/response/上下文路径等对象
- Java 开打一个文件夹,获取文件夹的路径
- 获取Java程序运行的路径
- Java获取程序路径
- java程序获取文件的路径
- 一个深入理解JAVA传统线程对象创建的例子
- 分享非常有用的Java程序 (关键代码) (二)---JavaSript获取上传文件路径的文件名
- Java写的一个二叉树三种遍历递归算法(仅用作理解三种遍历)
- 分享非常有用的Java程序 (关键代码) (二)---JavaSript获取上传文件路径的文件名
- java 如何获取程序运行时的相对路径
- 一个简单的获取百度贴吧上ID的java程序
- 第一个java小程序 applet 画一个圆 获取网页自定义的参数来输出
- java 程序获取路径(保留)
- 用Java程序获取绝对路径
- java中获取程序路径方法整理