二叉树的前序中序后序遍历--递归和非递归两种方式(Java实现)

 

 

简单介绍一下:

前序遍历:父节点--左孩子节点--右孩子节点

中序遍历:左孩子节点--父节点--右孩子节点

后序遍历:左孩子节点--右孩子节点--父节点

前中后指的是父节点在整个树的处理过程中次序。

代码:

实体类:

/**
 * @author yinglala
 */
public class BinaryTree {
    private int data;
    private BinaryTree lchild;
    private BinaryTree rchild;

    public BinaryTree(int data) {
        this.data = data;
    }


    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public BinaryTree getLchild() {
        return lchild;
    }

    public void setLchild(BinaryTree lchild) {
        this.lchild = lchild;
    }

    public BinaryTree getRchild() {
        return rchild;
    }

    public void setRchild(BinaryTree rchild) {
        this.rchild = rchild;
    }
}

遍历方法:



import java.util.Stack;

/**
 * @author yinglala
 */
public class BinaryTreeOrder {

    //前序遍历
    private static void preOrder(BinaryTree t){
        if(t == null){
            return;
        }
        System.out.print(t.getData() + " ");
        preOrder(t.getLchild());
        preOrder(t.getRchild());
    }


    //中序遍历
    private static void inOrder(BinaryTree t){
        if (t == null){
            return;
        }
        inOrder(t.getLchild());
        System.out.print(t.getData() + " ");
        inOrder(t.getRchild());
    }


    //后续遍历
    private static void postOrder(BinaryTree t){
        if(t == null){
            return;
        }
        postOrder(t.getLchild());
        postOrder(t.getRchild());
        System.out.print(t.getData() + " ");
    }

    //非递归版本

    //非递归前序遍历
    private static void nonRecursivePreOrder(BinaryTree t){
        if( t == null){
            return;
        }
        Stack<BinaryTree> stack = new Stack();
        stack.push(t);

        //栈不为空 进行弹出等操作
        while (stack != null && stack.size() != 0){
            //弹出栈顶元素
            BinaryTree tmpTree = stack.pop();
            //打印
            System.out.print(tmpTree.getData() + " ");

            //若tmpTree同时存在左子树和右子树 先对右子树进行压栈 再对左子树进行压栈
            //根据栈的特性 左子树位于栈顶 先弹出左子树 再弹出右子树
            if(tmpTree.getRchild() != null){
                stack.push(tmpTree.getRchild());
            }

            if(tmpTree.getLchild() != null){
                stack.push(tmpTree.getLchild());
            }
        }

    }

    //非递归版本中序遍历
    private static void nonRecursiveInOrder(BinaryTree t){
        if(t == null){
            return;
        }
        Stack<BinaryTree> stack = new Stack();
        stack.push(t);
        //初始化辅助节点P
        BinaryTree p = t;
        while(stack != null && stack.size() != 0){
            //如果左孩子不为空 先压栈
            if(p != null && p.getLchild() != null){
                stack.push(p.getLchild());
                p = p.getLchild();
            }else {
                //弹出栈顶元素
                p = stack.pop();
                //打印
                System.out.print(p.getData() + " ");
                if(p.getRchild() != null){
                    stack.push(p.getRchild());
                    p = p.getRchild();
                }else {
                    //p = stack.pop(); p已经访问过了 将p设置为空
                    p = null;
                }

            }


        }
    }

    //非递归版本后序遍历
    private static void nonRecursivePostOrder(BinaryTree t){
        if(t == null){
            return;
        }
        Stack<BinaryTree> stack = new Stack();
        stack.push(t);
        BinaryTree p = t;
        BinaryTree tVisit = null;
        while(stack != null && stack.size() != 0){
            //如果左孩子不为空 先压栈
            if(p != null && p.getLchild() != null){
                stack.push(p.getLchild());
                p = p.getLchild();
            }else{
                p = stack.peek();//获取栈顶元素 并保证p不为空

                //若没有右孩子,或者右孩子已经被访问过
                if(p.getRchild() == null || p.getRchild() == tVisit){
                    //打印
                    System.out.print(p.getData() + " ");
                    //标明上个被访问的节点 防止在回溯的过程中无限访问右孩子节点
                    tVisit = p;
                    p = null;
                    //栈顶元素及其孩子节点已访问 出栈
                    stack.pop();
                }else{
                    stack.push(p.getRchild());
                    p = p.getRchild();
                }
            }


        }
    }

    public static void main(String[] args){
        BinaryTree root = new BinaryTree(1);
        BinaryTree second = new BinaryTree(2);
        BinaryTree three = new BinaryTree(3);
        BinaryTree four = new BinaryTree(4);
        BinaryTree five = new BinaryTree(5);
        BinaryTree six = new BinaryTree(6);
        BinaryTree seven = new BinaryTree(7);
        root.setLchild(second);
        root.setRchild(three);
        second.setLchild(four);
        second.setRchild(five);
        three.setLchild(six);
        three.setRchild(seven);

        System.out.println("递归先序遍历:");
        preOrder(root);
        System.out.println();
        System.out.println("递归中序遍历:");
        inOrder(root);
        System.out.println();
        System.out.println("递归后序遍历:");
        postOrder(root);
        System.out.println();
        System.out.println("非递归先序遍历:");
        nonRecursivePreOrder(root);
        System.out.println();
        System.out.println("非递归中序遍历:");
        nonRecursiveInOrder(root);
        System.out.println();
        System.out.println("非递归后序遍历:");
        nonRecursivePostOrder(root);

    }


}

执行结果:

递归先序遍历:
1 2 4 5 3 6 7 
递归中序遍历:
4 2 5 1 6 3 7 
递归后序遍历:
4 5 2 6 7 3 1 
非递归先序遍历:
1 2 4 5 3 6 7 
非递归中序遍历:
4 2 5 1 6 3 7 
非递归后序遍历:
4 5 2 6 7 3 1 
Process finished with exit code 0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章