Java实现二叉树的三种非递归遍历

Java 实现二叉树的三种非递归遍历

1.思路

其实思路就是递归的思路,无非就是加入了栈这个数据结构。

具体来看代码吧,个人觉得还算简洁。

2.实现

首先是结点数据结构的设置:
/**
 * @author WK
 */
public class SearchBinaryTree {

    //存放的结点标志
    public String tag = "";
    //是否被便利的标志
    public boolean flag = false;
    //左孩子
    public SearchBinaryTree leftChild = null;
    //右孩子
    public SearchBinaryTree rightChild = null;
  //省略了getter,setter以及构造函数
}
- 前序遍历
/**
     *
     * @param T 传入的树的根结点
     */
    public static void priorOrderNonRecursive(SearchBinaryTree T) {
        //构造stack
        Stack<SearchBinaryTree> binaryTrees = new Stack<>();
        SearchBinaryTree p = T;

        //保证所有节点被遍历过
        while (p != null || (!binaryTrees.empty())) {

            //未被遍历则输出tag,入栈
            if (p.flag == false) {
                System.out.println(p.tag);
                p.flag = true;
                binaryTrees.push(p);
            }
            //左孩子不为空且左孩子未被遍历过(防止重复入栈)
            if (p.leftChild != null && p.leftChild.flag == false) {
                p = p.leftChild;
                continue;
            }
            //右孩子不为空且右孩子未被遍历过(防止重复入栈)
            if (p.rightChild != null && p.rightChild.flag == false) {
                p = p.rightChild;
                continue;
            }

            //如果左右孩子都为空则需要出栈。
            if (!binaryTrees.empty())
                p = binaryTrees.pop();
            else
                p = null;

        }

    }
- 中序遍历
 /**
     * 中序遍历和前序的区别就在于遍历的位置,也就是输出tag的位置,其他完全类似
     * @param root 传入的树的根结点
     */
    public static void infixOrderNonRecursive(SearchBinaryTree root) {
        Stack<SearchBinaryTree> binaryTrees = new Stack<>();
        SearchBinaryTree p = root;
        while (p != null || (!binaryTrees.empty())) {

            if (p.flag == false)
                binaryTrees.push(p);
            if (p.leftChild != null && p.leftChild.flag == false) {
                p = p.leftChild;
                continue;
            }

            if (p.flag == false) {
                System.out.println(p.tag);
                p.flag = true;

            }
            if (p.rightChild != null && p.rightChild.flag == false) {
                p = p.rightChild;
                continue;
            }

            if (!binaryTrees.empty())
                p = binaryTrees.pop();
            else
                p = null;

        }
    }
- 后序遍历
/**
     *可以发现其实后序遍历的代码与前两个也类似,只是遍历位置不同,由此可见非循环遍历其实也并不难,掌握其中一个其他的也就掌握了
     * @param root
     */
    public static void postOrderNonRecursive(SearchBinaryTree root) {
        Stack<SearchBinaryTree> binaryTrees = new Stack<>();
        SearchBinaryTree p = root;
        while (p != null || (!binaryTrees.empty())) {

            if (p.flag == false)
                binaryTrees.push(p);
            if (p.leftChild != null && p.leftChild.flag == false) {
                p = p.leftChild;
                continue;
            }


            if (p.rightChild != null && p.rightChild.flag == false) {
                p = p.rightChild;
                continue;
            }

            if (p.flag == false) {
                System.out.println(p.tag);
                p.flag = true;

            }
            if (!binaryTrees.empty())
                p = binaryTrees.pop();
            else
                p = null;

        }
    }

3.测试

以这棵树为例:

example

初始化代码:

private static SearchBinaryTree initTree() {
        SearchBinaryTree A = new SearchBinaryTree("A");
        SearchBinaryTree B = new SearchBinaryTree("B");
        SearchBinaryTree C = new SearchBinaryTree("C");
        SearchBinaryTree D = new SearchBinaryTree("D");
        SearchBinaryTree E = new SearchBinaryTree("E");
        SearchBinaryTree F = new SearchBinaryTree("F");
        SearchBinaryTree G = new SearchBinaryTree("G");
        A.leftChild = B;
        A.rightChild = F;
        B.leftChild = C;
        B.rightChild = D;
        D.leftChild = E;
        F.leftChild = G;

        return A;
    }

测试:

  SearchBinaryTree root = initTree();
        System.out.println("--------前序遍历开始:");
        priorOrderNonRecursive(root);
        System.out.println("--------中序遍历开始:");
        root = initTree();
        infixOrderNonRecursive(root);
        System.out.println("--------后序遍历开始:");
        root = initTree();
        postOrderNonRecursive(root);

结果:

--------前序遍历开始:
A
B
C
D
E
F
G
--------中序遍历开始:
C
B
E
D
A
G
F
--------后序遍历开始:
C
E
D
B
G
F
A

3.总结

实现之后发现静下心来思考的话这个问题并不难,说明对其他事物来讲也应该这样,静心下来去做。

转载请注明出处:http://blog.csdn.net/CSDNOfWK/article/details/78505862

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值