二叉树的先序中序后续遍历(递归非递归)
转载:http://blog.csdn.net/jssongwei/article/details/50790253
首先来看一棵二叉树:
1、前序遍历:
前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
若二叉树为空则结束返回,否则:
(1)访问根结点;
(2)前序遍历左子树;
(3)前序遍历右子树 ;
需要注意的是:遍历左右子树时仍然采用前序遍历方法。可以看出前序遍历后,遍历结果为:631254978
2、中序遍历:
中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。即:
若二叉树为空则结束返回,否则:
(1)中序遍历左子树;
(2)访问根结点;
(3)中序遍历右子树;
注意的是:遍历左右子树时仍然采用中序遍历方法。最上图的二叉树用中序遍历的结果是:123456789
3、后续遍历:
后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。即:
若二叉树为空则结束返回,否则:
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根结点;
如图所示的二叉树,用后序遍历的结果是:214538796
三种遍历的递归实现:
- public class Node {//二叉树节点
- private int data;
- private Node leftNode;
- private Node rightNode;
- public Node(int data, Node leftNode, Node rightNode){
- this.data = data;
- this.leftNode = leftNode;
- this.rightNode = rightNode;
- }
- public int getData(){
- return data;
- }
- public void setData(int data){
- this.data = data;
- }
- public Node getLeftNode(){
- return leftNode;
- }
- public void setLeftNode(Node leftNode){
- this.leftNode = leftNode;
- }
- public Node getRightNode(){
- return rightNode;
- }
- public void setRightNode(Node rightNode){
- this.rightNode = rightNode;
- }
- }
三种遍历的递归实现:
- public class BinaryTree_DiGui {
- /*
- * 二叉树先序中序后序排序
- * 方式:递归。
- */
- //注意必须逆序简历,先建立子节点,再逆序往上建立,
- //因为非叶子节点会使用到下面的节点,而初始化是按顺序初始化得,不逆序建立会报错
- public static Node init(){
- Node J = new Node(8, null, null);
- Node H = new Node(4, null, null);
- Node G = new Node(2, null, null);
- Node F = new Node(7, null, J);
- Node E = new Node(5, H, null);
- Node D = new Node(1, null, G);
- Node C = new Node(9, F, null);
- Node B = new Node(3, D, E);
- Node A = new Node(6, B, C);
- return A; //返回根节点
- }
- //打印节点数值
- public static void printNode(Node node){
- System.out.print(node.getData());
- }
- //先序遍历
- public static void preOrder(Node root){
- printNode(root);//打印根节点
- if(root.getLeftNode() != null){//使用递归遍历左孩子
- preOrder(root.getLeftNode());
- }
- if(root.getRightNode() != null){//使用递归遍历右孩子
- preOrder(root.getRightNode());
- }
- }
- //中序遍历
- public static void inOrder(Node root){
- if(root.getLeftNode() != null){//使用递归遍历左孩子
- inOrder(root.getLeftNode());
- }
- printNode(root);//打印根节点
- if(root.getRightNode() != null){//使用递归遍历右孩子
- inOrder(root.getRightNode());
- }
- }
- //后续遍历
- public static void postOrder(Node root){
- if(root.getLeftNode() != null){//使用递归遍历左孩子
- postOrder(root.getLeftNode());
- }
- if(root.getRightNode() != null){//使用递归遍历右孩子
- postOrder(root.getRightNode());
- }
- printNode(root);//打印根节点
- }
- public static void main(String[] args){
- // BinaryTree tree = new BinaryTree();//注释掉本行后类中方法需变为static
- Node root = init();
- System.out.println("先序遍历");
- preOrder(root);
- System.out.println("");
- System.out.println("中序遍历");
- inOrder(root);
- System.out.println("");
- System.out.println("后序遍历");
- postOrder(root);
- System.out.println("");
- }
- }
通过栈实现三种遍历(非递归):
- public class BinaryTree_Zhan {
- /*
- *
- * 二叉树先序中序后序排序
- * 方式:采用非递归方式。
- */
- //注意必须逆序简历,先建立子节点,再逆序往上建立,
- //因为非叶子节点会使用到下面的节点,而初始化是按顺序初始化得,不逆序建立会报错
- public static Node init(){
- Node J = new Node(8, null, null);
- Node H = new Node(4, null, null);
- Node G = new Node(2, null, null);
- Node F = new Node(7, null, J);
- Node E = new Node(5, H, null);
- Node D = new Node(1, null, G);
- Node C = new Node(9, F, null);
- Node B = new Node(3, D, E);
- Node A = new Node(6, B, C);
- return A; //返回根节点
- }
- //打印节点数值
- public static void printNode(Node node){
- System.out.print(node.getData());
- }
- public static void preOrder_stack(Node root){//先序遍历
- Stack<Node> stack = new Stack<Node>();
- Node node = root;
- while(node != null || stack.size()>0){//将所有左孩子压栈
- if(node != null){//压栈之前先访问
- printNode(node);
- stack.push(node);
- node = node.getLeftNode();
- }else{
- node = stack.pop();
- node = node.getRightNode();
- }
- }
- }
- public static void inOrder_Stack(Node root){//中序遍历
- Stack<Node> stack = new Stack<Node>();
- Node node = root;
- while(node != null || stack.size()>0){
- if(node != null){
- stack.push(node);//直接压栈
- node = node.getLeftNode();
- }else{
- node = stack.pop();//出栈并访问
- printNode(node);
- node = node.getRightNode();
- }
- }
- }
- public static void postOrder_Stack(Node root){//后续遍历
- Stack<Node> stack = new Stack<Node>();
- Stack<Node> output = new Stack<Node>();//构造一个中间栈来存储逆后续遍历的结果
- Node node = root;
- while(node != null || stack.size()>0){
- if(node != null){
- output.push(node);
- stack.push(node);
- node = node.getRightNode();
- }else{
- node = stack.pop();
- node = node.getLeftNode();
- }
- }
- while(output.size()>0){
- printNode(output.pop());
- }
- }
- public static void main(String[] args){
- Node root = init();
- System.out.println("先序遍历");
- preOrder_stack(root);
- System.out.println("");
- System.out.println("中序遍历");
- inOrder_Stack(root);
- System.out.println("");
- System.out.println("后序遍历");
- postOrder_Stack(root);
- System.out.println("");
- }
- }