使用java实现一棵二叉树,并使用他完成二叉树的层次遍历,两种中序遍历 递归 &非递归

层次遍历:

层次遍历二叉树,使用了队列结构-Queue(先进先出)来实现。

先将根节点入队列,只要队列不为空,然后出队列并访问,接着将访问节点的左右子树依次入队列。如此操作,可以保证上层的节点一定会在下层之前输出。

//层次
public int[] levelOrder(TreeNode root) {
        if(root==null) return new int[0];
        List<Integer> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        //TreeNode node = root;
        queue.add(root);
        while(!queue.isEmpty()){
            TreeNode node = queue.poll();
            list.add(node.val);
            if(node.left!=null){
               queue.add(node.left);
            }
            if(node.right!=null){
                queue.add(node.right);
            }
        }
        int [] res = new int [list.size()];
        for(int i=0;i<res.length;i++){
            //当i为1时,获取list中的第一个元素
            res[i]=list.get(i);
        }
        return res;
    }

 先序、中序、后序遍历关系:

先序遍历(根左右):

考察到一个节点后,立刻输出该节点的值,然后继续遍历其左右子树;
根在前,从左往右,一棵树的根永远在左子树前面,左子树又永远在右子树前面;
核心:先输出自己,再遍历子树。


中序遍历(左根右):

考察到一个节点后,将其暂存,遍历完左子树后,再输出该节点的值,然后遍历右子树;
根在中,从左往右,一棵树的左子树永远在根前面,根永远在右子树前面;
核心:自己的左子没有数据,才将自己输出。


后序遍历(左右根):

考察到一个节点后,将其暂存,遍历完左右子树后,再输出该节点的值;
根在后,从左往右,一棵树的左子树永远在右子树前面,右子树永远在根前面;
核心:自己的左子和右子都没有数据,才将自己输出。

递归:先中后序遍历

public void preOrder(TreeNode root){
    List<TreeNode> list = new ArrayList<>();
    if(root==null) return;
    list.add(root);
    if(root.left!=null){
        preOrder(root.left);
    }
    if(root.right!=null){
        preOrder(root.right);
    }
}
//递归 -中序
public void inOrder(TreeNode root){
    List<TreeNode> list = new ArrayList<>();
    if(root==null) return;
    if(root.left!=null){
        preOrder(root.left);
    }
    list.add(root);
    if(root.right!=null){
        preOrder(root.right);
    }
}
//递归 -后续
public void postOrder(TreeNode root){
    List<TreeNode> list = new ArrayList<>();
    if(root==null) return;
    if(root.left!=null){
        preOrder(root.left);
    }
    if(root.right!=null){
        preOrder(root.right);
    }
    list.add(root);
}

非递归:先中后遍历

//非递归-先序
public void preOrder(TreeNode root){
    List<Integer> list = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    while(root!=null||!que.isEmpty()){
        //一直往二叉树的左子树上走
        while(root!=null){
            list.add(root.val);
            stack.push(root);
            root = root.left;
        }
        //左边的节点都走完了 改变节点方向
        if(!stack.isEmpty()){
            root = stack.pop();
            root=root.right;
        }
    }
}
 
//非递归-中序
public void inOrder(TreeNode root){
    List<Integer> list = new ArrayList<>();//结果
    Stack<TreeNode> stack = new Stack<>();
    while(root!=null||!que.isEmpty()){
        一直向左,但是先不存入
        while(root!=null){
            stack.push(root);
            root = root.left;
        }
        //左边的节点都走完了 存入list并 改变节点方向
        if(!stack.isEmpty()){
            root = stack.pop();
            list.add(root.val);
            root=root.right;
        }
    }
}
 
//非递归-后序
public void postOrder(TreeNode root){
    List<Integer> list = new ArrayList<>();//结果
    Stack<TreeNode> stack = new Stack<>();
    while(root!=null||!que.isEmpty()){
        //一直向右
        while(root!=null){
            list.add(root.val)
            stack.push(root);
            root = root.right;
        }
        if(!stack.isEmpty()){
            root = stack.pop();
            root=root.left;
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值