数据结构-二叉树-二叉树的前序、中序、后序遍历(通过递归与非递归方法实现)、层序遍历

首先创建树类

public class tree {
    private Object data;
    private tree left;
    private tree right;

    public Object getData() {
        return data;
    }

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

    public tree getLeft() {
        return left;
    }

    public void setLeft(tree left) {
        this.left = left;
    }

    public tree getRight() {
        return right;
    }

    public void setRight(tree right) {
        this.right = right;
    }
}

树的建立(通过前序创建)

树的节点创建为String,当遇到#时表明到头

public void create(tree TREE){
        Scanner s= new Scanner(System.in);
        String a = s.next();
        if(a.equals("#")) {  //如果当前输入#则表明不创建
            return;
        }
        else
            TREE.setData(a);
        TREE.setLeft(new tree());   //创建左子树
        create(TREE.getLeft());
        TREE.setRight(new tree());  //创建右子树
        create(TREE.getRight());   
    }

递归遍历

递归遍历比较容易实现,前序表明每次到达一个节点就立即输出,中序是中间输出,后序是遍历完左右子树后输出。通过递归可以非常简单的实现。

前序

public void prePrint(tree t){
        if(t==null) return ;
        if (t.getData()!=null)
            System.out.print(t.getData()+" ");
        prePrint(t.getLeft());
        prePrint(t.getRight());
    }

中序

public void inPrint(tree t){
        if(t==null) return ;
        inPrint(t.getLeft());
        if (t.getData()!=null)
            System.out.print(t.getData()+" ");
        inPrint(t.getRight());
    }

后序

public void postPrint(tree t){
        if(t==null) return ;
        postPrint(t.getLeft());
        postPrint(t.getRight());
        if (t.getData()!=null)
            System.out.print(t.getData()+" ");
    }

非递归遍历

非递归遍历二叉树需要用到栈,先来说明前序和中序的实现。
(1)每次都将到达的节点入栈,然后进入左子树,一直到尽头。
(2)走到头时,从栈顶弹出最近一个节点,进入此节点的右子树,重复第一步。
(3)当栈空且当前节点为空时说明已经遍历完毕。
前序遍历时入栈之前直接输出。中序遍历时在弹出栈时输出。

前序

public void NRPrePrint(tree t){
        Stack<tree> stack = new Stack<>();
        tree temp;
        if(t == null) return ;
        temp = t;
        while(!(temp==null&&stack.empty())){//栈空且当前节点为空不同时成立
            while(temp!=null){   //向左子树走
                if(temp.getData()!=null)    //前序第一次直接输出
                    System.out.print(temp.getData()+" ");
                stack.push(temp);
                temp = temp.getLeft();
            }
            if(stack.empty()) return;
            else {     //左子树走完后向栈顶节点的右子树走
                temp = stack.pop();
                temp = temp.getRight();
            }
        }
    }

中序

public void NRInPrint(tree t){
        Stack<tree> stack = new Stack<>();
        tree temp;
        if(t == null) return ;
        temp = t;
        while(!(temp==null&&stack.empty())){
            while(temp!=null){

                stack.push(temp);
                temp = temp.getLeft();
            }
            if(stack.empty()) return;
            else {
                temp = stack.pop();
                if(temp.getData()!=null)    //弹出栈时输出
                    System.out.print(temp.getData()+" ");
                temp = temp.getRight();

            }
        }
    }

后序

后序遍历的思想为第二次遇到此节点时才输出。第一次不将节点弹出,而是直接进入右子树。当节点的右子树为空时,将此节点输出,并将此节点值设为空,表示此节点已经输出。下一次遇到此节点的父节点时,通过父节点将此节点设为空。

这种方法会破环树的结构,遍历完后树会变空

public void NRPostPrint(tree tree){
        Stack<tree> stack = new Stack<>();
        tree temp;
        if(tree == null) return ;
        temp = tree;
        while(!(temp ==null&&stack.empty())){
            while(temp!=null){
                    stack.push(temp);
                    temp = temp.getLeft();
            }
            if (stack.empty()) return;
            else {
                temp = stack.peek();
                if(temp.getRight()!=null){
                    if(temp.getRight().getData()==null){
                        temp.setRight(null);
                    }
                    temp = temp.getRight();
                }
                else {
                    temp = stack.pop();
                    if(temp.getData()!=null)
                        System.out.print(temp.getData()+" ");
                    temp.setData(null);//此处如果只写temp = null 不能把此子树消除,必须把data设为空然后
                                          //在下一次循环使用setRight()方法
                    temp = null;
                }
            }
        }
    }

树的层序遍历

层序遍历:首先将根节点入队。然后当队不空时,从队中取出头节点,输出此节点,然后将此节点的左右子树也入队。

public void levelPrint(tree t){
        if(t == null) return;
        Queue<tree> queue = new LinkedList<>();
        tree temp;
        queue.offer(t);
        while(!queue.isEmpty()){
            temp = queue.poll();
            if (temp.getData()!=null)
                System.out.print(temp.getData()+" ");
            if(temp.getLeft()!=null)
                queue.offer(temp.getLeft());
            if(temp.getRight()!=null)
                queue.offer(temp.getRight());
        }
    }

主函数

public static void main(String args[]){
        treeList treeList = new treeList();
        tree t=new tree();
        treeList.create(t);
        System.out.println("层序遍历:");
        treeList.levelPrint(t);System.out.println();
        System.out.println("树的递归遍历:");
        treeList.prePrint(t);System.out.println("前序");
        treeList.inPrint(t);System.out.println("中序");
        treeList.postPrint(t);System.out.println("后序");
        System.out.println("树的非递归遍历:");
        treeList.NRPrePrint(t);System.out.println("前序");
        treeList.NRInPrint(t);System.out.println("中序");
        treeList.NRPostPrint(t);System.out.println("后序");

    }

在这里插入图片描述
运行结果
首先按照先序顺序输入树
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值