二叉树的遍历--用递归 和栈 实现 前序、中序、后序遍历
import java.util.HashMap; import java.util.Map; import java.util.Stack; /** * 作者:用递归 和栈 实现 前序、中序、后序遍历 * 功能说明: */ public class BinarayTree { Node<String> root; /** * 构造器 * @param data */ public BinarayTree(String data) { super(); root=new Node<String>(data, null, null); } /** * 栈+循环 实现 后序遍历 * @param root * 思路 后序遍历不同于先序和中序,它是要先处理完左右子树,然后再处理根(回溯),所以需要一个记录哪些节点已经被访问的结构(可以在树结构里面加一个标记),这里可以用map实现 */ public void postOrderTraverse2(Node root){ if(root==null)return; Stack<Node<String>> stack=new Stack<>(); Map<Node<String>,Boolean> map=new HashMap<Node<String>,Boolean>(); stack.push(root); while(!stack.isEmpty()){ Node temp=stack.peek(); //peek 返回栈顶的值,但不移出栈 (pop移出栈) if(temp.leftChild!=null && !map.containsKey(temp.leftChild)){ temp=temp.leftChild; while(temp!=null){ if(map.containsKey(temp)){ break; } else{ stack.push(temp); } temp=temp.leftChild; } continue; } if(temp.rightChild!=null&&!map.containsKey(temp.rightChild)){ stack.push(temp.rightChild); continue; } Node t=stack.pop(); map.put(t,true); System.out.print(" : "+t.data); } } /** * 栈+循环 实现 前序遍历 * @param root * 思路 只要栈里面有元素 就轮循 */ public void preOrderTraverse2(Node root){ if(root ==null){ return; } Stack<Node<String>> stack=new Stack<>(); stack.push(root); while (!stack.isEmpty()) { Node<String> curNode= stack.pop();//栈顶元素出站 System.out.print(" : "+curNode.data); //有坑 注意非空判断 if(curNode.rightChild!=null){ stack.push(curNode.rightChild); } if(curNode.leftChild!=null){ stack.push(curNode.leftChild);; } } } /** * 栈+循环 实现 中序遍历 * @param root * 思路 左子树都处理完直到null的时候出栈并访问。 */ public void mirOrderTraverse2(Node root){ if(root ==null){ return; } Stack<Node<String>> stack=new Stack<>(); while(root!=null || !stack.isEmpty()){ while(root!=null){ stack.push(root);//先访问再入栈 root=root.leftChild; } root=stack.pop(); //出栈 System.out.print(" : "+root.data); root=root.rightChild;//如果是null,出栈并处理右子树 } } /** * 递归算法 前序遍历 * @param root */ public void preOrderTraverse1(Node root){ if(root ==null){ return; } System.out.print(" : "+root.data); preOrderTraverse1(root.leftChild); preOrderTraverse1(root.rightChild); } /** * 递归算法 中序遍历 * @param root */ public void mirOrderTraverse1(Node root){ if(root==null){ return; } mirOrderTraverse1(root.leftChild); System.out.print (" : "+root.data); mirOrderTraverse1(root.rightChild); } /** * 递归算法 后序遍历 * @param root */ public void postOrderTraverse1(Node root){ if(root==null){ return; } postOrderTraverse1(root.leftChild); postOrderTraverse1(root.rightChild); System.out.print(" : "+root.data); } /** * 定义类 * @version 创建时间: 2017-11-14 下午10:26:07 * 类说明: */ public class Node<T>{ T data; Node leftChild; Node rightChild; public Node(T data, Node leftChild, Node rightChild) { super(); this.data = data; this.leftChild = leftChild; this.rightChild = rightChild; } }
/** * 构建二叉树 * A * B C * D E F */ public void createTree(){ Node<String> nodeB =new Node<String>("B", null, null); Node<String> nodeC =new Node<String>("C", null, null); Node<String> nodeD =new Node<String>("D", null, null); Node<String> nodeE =new Node<String>("E", null, null); Node<String> nodeF =new Node<String>("F", null, null); root.leftChild=nodeB; root.rightChild=nodeC; nodeB.leftChild=nodeD; nodeB.rightChild=nodeE; nodeC.rightChild=nodeF; } public static void main(String[] args) { BinarayTree tree=new BinarayTree("A");//传递的是根节点的值 tree.createTree(); System.out.println("递归 前序遍历:正确顺序值 A B D E C F"); tree.preOrderTraverse1(tree.root); System.out.println(); System.out.println("栈+循环 前序遍历:正确顺序值 A B D E C F"); tree.preOrderTraverse2(tree.root); System.out.println(); System.out.println("------------------------------"); System.out.println("递归 中序遍历:正确顺序值 D B E A C F"); tree.mirOrderTraverse1(tree.root); System.out.println(); System.out.println("栈+循环 中序遍历:正确顺序值D E B F C A"); tree.mirOrderTraverse2(tree.root); System.out.println(); System.out.println("------------------------------"); System.out.println("递归 后序遍历:正确顺序值 D E B F C A"); tree.postOrderTraverse1(tree.root); System.out.println(); System.out.println("栈+循环 后序遍历:正确顺序值D E B F C A"); tree.postOrderTraverse2(tree.root); }}
运行结果如下: