二叉树前序、中序、后序遍历(递归版、非递归版)

复习二叉树的遍历,自己实现了一遍代码,在这里进行下记录,递归和非递归都写出来了,感谢各位的批评指正。

节点定义:

package com.al;

public class Node {

    public String value;
    public Node leftNode;
    public Node rightNode;

    public Node(String value) {
        this.value = value;
    }
}

递归版:

package com.al;
/**
 * 递归版
 * @author MSI
 *
 */
public class recursionTraversal {
    //前序
    public static void DLR(Node root) {
        if (root == null) {
            return;
        } else {
            System.out.print(root.value + " ");
            DLR(root.leftNode);
            DLR(root.rightNode);
        }
    }
    //中序
    public static void LDR(Node root) {
        if (root == null) {
            return;
        } else {
            LDR(root.leftNode);
            System.out.print(root.value + " ");
            LDR(root.rightNode);
        }
    }
    //后序
    public static void LRD(Node root) {
        if (root == null) {
            return;
        } else {
            LRD(root.leftNode);
            LRD(root.rightNode);
            System.out.print(root.value + " ");
        }
    }

}

非递归版:(因为递归都可以用栈进行实现)
package com.al;

import java.util.Stack;

/**
* 非递归遍历
*
* @author MSI
*
*/
public class nonRecursionTraversal {

// 前序遍历
/**
 * 1. 申请一个新的栈,记为 stack。然后将头节点 root 压入 stack 中。
 * 2. 从 stack中弹出栈顶节点,记为root,然后打印root 节点的值,
 *     再将节点 root 的右孩 子(不为空的话)先压入 stack 中, 最后将 root 的左孩子(不为空的话继续进行压栈)。 
 * 3. 不断重复步骤 2,直到 stack 为空,全部过程结束。
 * 
 * @param root
 */
public static void DLR(Node root) {
    if (root != null) {
        Stack<Node> stack = new Stack<Node>();
        stack.add(root);
        while (!stack.isEmpty()) {
            root = stack.pop();
            System.out.print(root.value + " ");
            if (root.rightNode != null) {
                stack.add(root.rightNode);
            }
            if (root.leftNode != null) {
                stack.add(root.leftNode);
            }
        }
    }
}

// 中序遍历
/**
 * 1.申请一个新的栈,记为 stack。初始时,令变量 cur=root。 
 * 2.先把 cur 节点压入栈中,对以 cur 节点为头的整棵子树来说,依次把左边界压入栈 中,即不停地令 cur=cur.leftNode,
 *    然后重复步骤 2。 
 * 3.不断重复步骤 2,直到发现 cur为空,此时从 stack 中弹出一个节点,记为 node。
 *    打印 cur 的值,并且让 cur=cur.rightNode,然后继续重复步骤 2。
 * 4.当 stack 为空且 cur 为空时,整个过程停止。
 * 
 * @param root
 */
public static void LDR(Node root) {
    if (root != null) {
        Stack<Node> stack = new Stack<Node>();
        // 若栈不为空,且节点不为空,一直循环执行
        while (!stack.isEmpty() || root != null) {
            // 若当前节点不空。则继续往左子树下探;
            if (root != null) {
                stack.push(root);
                root = root.leftNode;
            } else {// 否则将当前栈顶元素弹出,并将往右子树下探;
                root = stack.pop();
                System.out.print(root.value + " ");
                root = root.rightNode;
            }
        }
    }
}

// 后序遍历
/**
 * 1.申请一个栈,记为 s1,然后将头节点 root 压入 s1 中。 
 * 2.从 s1 中弹出的节点记为 cur,然后依次将 cur的左孩子和右孩子压入 s1 中。 
 * 3.在整个过程中,每一个从 s1 中弹出的节点都放进 s2 中。 
 * 4.不断重复步骤 2 和步骤 3,直到 s1为空,过程停止。
 * 5.从 s2 中依次弹出节点并打印,打印的顺序就是后序遍历的顺序。
 * 
 * @param root
 */
public static void LRD(Node root) {
    if (root != null) {
        Stack<Node> s1 = new Stack<Node>();
        Stack<Node> s2 = new Stack<Node>();
        s1.push(root);
        while (!s1.isEmpty()) {
            root = s1.pop();
            s2.push(root);
            if (root.leftNode != null) {
                s1.push(root.leftNode);
            }
            if (root.rightNode != null) {
                s1.push(root.rightNode);
            }
        }
        while (!s2.isEmpty()) {
            System.out.print(s2.pop().value + " ");
        }
    }
}

}

最后一起进行测试:

package com.al;

public class Test {

    public static void main(String[] args) {
        //定义二叉树结构
        Node root = new Node("A");
        root.leftNode = new Node("B");
        root.rightNode = new Node("C");
        root.leftNode.leftNode = new Node("D");
        root.leftNode.rightNode = new Node("E");
        root.rightNode.leftNode = new Node("F");
        root.rightNode.rightNode = new Node("G");

        /**
         * 递归版
         */
        System.out.println("递归版:");
        System.out.print("前序遍历:");
        recursionTraversal.DLR(root);
        System.out.println();
        System.out.print("中序遍历:");
        recursionTraversal.LDR(root);
        System.out.println();
        System.out.print("后序遍历:");
        recursionTraversal.LRD(root);
        System.out.println("\n"+"------------------------");
        /**
         * 非递归版
         */
        System.out.println("非递归版:");
        System.out.print("前序遍历:");
        nonRecursionTraversal.DLR(root);
        System.out.println();
        System.out.print("中序遍历:");
        nonRecursionTraversal.LDR(root);
        System.out.println();
        System.out.print("后序遍历:");
        nonRecursionTraversal.LRD(root);
        System.out.println();
    }
}

输出结果:

控制台输出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值