1.二叉树遍历:逻辑、具体算法理解即可,不必自己写出来. //太复杂了.
2.整理理解:
原文参考:http://blog.csdn.net/oney139/article/details/8063953
二叉树遍历 BinTree
package edu.yhf.demo.binaryTree; import java.util.Stack; /** * 二叉树遍历 * @author lengzl * @email [email protected] * @create 2017年2月9日 下午3:20:02 * 原文参考:http://blog.csdn.net/oney139/article/details/8063953 */ public class BinTree { protected BTNode root; public BinTree(BTNode root) { this.root = root; } public BTNode getRoot() { return root; } /** 构造树I H / \ D G / \ \ B C F \ / A E * @author lengzl * @email [email protected] * @create 2017年2月9日 上午9:39:00 * @return */ public static BTNode init() { /* BTNode a = new BTNode('A'); BTNode b = new BTNode('B', null, a); BTNode c = new BTNode('C'); BTNode d = new BTNode('D', b, c); BTNode e = new BTNode('E'); BTNode f = new BTNode('F', e, null); BTNode g = new BTNode('G', null, f); BTNode h = new BTNode('H', d, g); //根节点 BTNode */ /** 构造树II A / \ B C / \ \ D E F / / \ G N I / \ J K */ /* * 左边树 */ BTNode j = new BTNode('J'); BTNode g = new BTNode('G',j,null); BTNode e = new BTNode('E',g,null); BTNode d = new BTNode('D'); BTNode b = new BTNode('B',d,e); /* * 右边树 */ BTNode k = new BTNode('K'); BTNode n = new BTNode('N',null,k); BTNode i = new BTNode('I'); BTNode f = new BTNode('F',n,i); BTNode c = new BTNode('C',null,f); BTNode h = new BTNode('A',b,c); return h;// root } /** * 访问节点,打印操作 * @author lengzl * @email [email protected] * @create 2017年2月9日 下午3:19:50 * @param p */ public static void visit(BTNode p) { System.out.print(p.getKey() + " "); } /** 递归实现前序遍历 */ protected static void preorder(BTNode p) { if (p != null) { visit(p); //只是打印值 preorder(p.getLeft()); preorder(p.getRight()); } } /** 递归实现中序遍历 */ protected static void inorder(BTNode p) { if (p != null) { inorder(p.getLeft()); visit(p); inorder(p.getRight()); } } /** 递归实现后序遍历 */ protected static void postorder(BTNode p) { if (p != null) { postorder(p.getLeft()); postorder(p.getRight()); visit(p); } } /** 非递归实现前序遍历 */ protected static void iterativePreorder(BTNode p) { Stack<BTNode> stack = new Stack<BTNode>(); if (p != null) { stack.push(p); while (!stack.empty()) { p = stack.pop(); visit(p); if (p.getRight() != null) stack.push(p.getRight()); if (p.getLeft() != null) stack.push(p.getLeft()); } } } /** 非递归实现后序遍历 */ protected static void iterativePostorder(BTNode p) { BTNode q = p; Stack<BTNode> stack = new Stack<BTNode>(); while (p != null) { // 左子树入栈 for (; p.getLeft() != null; p = p.getLeft()) stack.push(p); // 当前节点无右子或右子已经输出 while (p != null && (p.getRight() == null || p.getRight() == q)) { visit(p); q = p;// 记录上一个已输出节点 if (stack.empty()) return; p = stack.pop(); } // 处理右子 stack.push(p); p = p.getRight(); } } /** * 非递归实现中序遍历 * 左-右-根 * @author lengzl * @email [email protected] * @create 2017年2月9日 下午4:59:19 * @param p */ protected static void iterativeInorder(BTNode p) { Stack<BTNode> stack = new Stack<BTNode>(); while (p != null) { while (p != null) { if (p.getRight() != null) stack.push(p.getRight());// 当前节点右子入栈 stack.push(p);// 当前节点入栈 p = p.getLeft(); } p = stack.pop(); while (!stack.empty() && p.getRight() == null) { visit(p); p = stack.pop(); } visit(p); if (!stack.empty()) p = stack.pop(); else p = null; } } public static void main(String[] args) { //构造树 BinTree tree = new BinTree(init()); System.out.print("(前序排列)Pre-Order:"); preorder(tree.getRoot()); System.out.println(); System.out.print("(中序排列)In-Order:"); inorder(tree.getRoot()); System.out.println(); System.out.print("(后序排列)Post-Order:"); postorder(tree.getRoot()); System.out.println(); System.out.print("(前序排列-非递归调用)Pre-Order:"); iterativePreorder(tree.getRoot()); System.out.println(); System.out.print("(中序排列-非递归调用)In-Order:"); iterativeInorder(tree.getRoot()); System.out.println(); System.out.print("(后序排列-非递归调用)Post-Order:"); iterativePostorder(tree.getRoot()); System.out.println(); } }
二叉树节点 BTNode
package edu.yhf.demo.binaryTree; /** 二叉树节点 */ public class BTNode { private char key; private BTNode left, right; public BTNode(char key) { this(key, null, null); } public BTNode(char key, BTNode left, BTNode right) { this.key = key; this.left = left; this.right = right; } public char getKey() { return key; } public void setKey(char key) { this.key = key; } public BTNode getLeft() { return left; } public void setLeft(BTNode left) { this.left = left; } public BTNode getRight() { return right; } public void setRight(BTNode right) { this.right = right; } }
树I显示结果:
(前序排列)Pre-Order:H D B A C G F E
(中序排列)In-Order:B A D C H G E F
(后序排列)Post-Order:A B C D E F G H
(前序排列-非递归调用)Pre-Order:H D B A C G F E
(中序排列-非递归调用)In-Order:B A D C H G E F
(后序排列-非递归调用)Post-Order:A B C D E F G H
树II显示结果
(前序排列)Pre-Order:A B D E G J C F N K I
(中序排列)In-Order:D B J G E A C N K F I
(后序排列)Post-Order:D J G E B K N I F C A
(前序排列-非递归调用)Pre-Order:A B D E G J C F N K I
(中序排列-非递归调用)In-Order:D B J G E A C N K F I
(后序排列-非递归调用)Post-Order:D J G E B K N I F C A
说明:
/*遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。 设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。 (1)先序遍历 访问根;按先序遍历左子树;按先序遍历右子树 (2)中序遍历 按中序遍历左子树;访问根;按中序遍历右子树 (3)后序遍历 按后序遍历左子树;按后序遍历右子树;访问根 (4)层次遍历 即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同) 个人感悟: */
/--2017/2/28 11:21:51
1.前序很容易理解;
中序最易出错.
中序,后序遍历都是从最左侧的单位开始,比如:树II.
中序遍历第一个节点是D,而非J. ★$)