94. 二叉树的遍历(非递归方式)

题目描述:
给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
   1
    \
     2
    /
   3

输出: [1,3,2]

进阶:: 递归算法很简单,你可以通过迭代算法完成吗?

解题思路:
本道题就是二叉树的遍历,我想到了两种办法,就是常规的递归实现和显示栈实现。

方法一:
递归,不多说。

    	 public List<Integer> inorderTraversal(TreeNode root) {
			 List<Integer> list = new ArrayList<>();
			 Inorder(root,list);
			 return list;
		 }
		 
		 
		 public void Inorder(TreeNode node,List<Integer> list) {
			 if (node != null) {
			 	//遍历左子树
				Inorder(node.left, list);
				list.add(node.val);
				//遍历右子树
				Inorder(node.right, list);
			}
		 }

**方法二:**通过迭代法,利用栈实现。主要思路就是,先将左子树入栈,即只要有左子结点就入栈,直到为空,然后出栈,记录val值,再访问右子树,访问右子树时,又先遍历右子树的左子树,依次类推,从而实现左、根、右的遍历顺序。

代码实现:

	 public List<Integer> inorderTraversal(TreeNode root) {
			 List<Integer> list = new ArrayList<>();
			 Stack<TreeNode> stack = new Stack<>();
			 
			 while(root != null || !stack.isEmpty()) {
				 //左子树入栈
				 while(root != null) {
					 stack.push(root);
					 root = root.left;
				 }
				 //获取当前结点(相当于当前子根节点)
				 TreeNode cur = stack.pop();
				 list.add(cur.val);
				 if (cur.right != null) {
					 root = cur.right;
				}
			 }
			 return list;
	 }

前序遍历:

    public List<Integer> preorderTraversal(TreeNode root) {
       List<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        
        while(root != null || !stack.isEmpty()){
            
            while(root != null){
                list.add(root.val);
                stack.push(root);
                root = root.left;
            }
      
             root  = stack.pop();
            root = root.right;
        }
        
        return list;
    }

后序遍历(重点):
在这里插入图片描述
手工写出:
先序遍历序列:1、2、3、5、4
后序遍历序列:3、5、2、4、1
把后序遍历逆序:1、4、2、5、3

观察发现,逆后序遍历和先序遍历序列有一定联系,逆后序遍历序列只不过是先序遍历过程中对左右子树遍历顺序交换得到的结果。

因此,只需要将前面的先序遍历算法中对左右子树遍历顺序交换就可以得到逆后序遍历序列,然后再将逆后序遍历序列逆序就得到了后序遍历序列。所以需要两个栈,一个栈stack1用来辅助作逆后序遍历,另一个栈stack2用来存放遍历结果,然后再将stack2全部出栈,即得到了后序遍历序列。

算法:

    	public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();
        
        while(!stack1.isEmpty() || root != null) {
        	while(root != null) {
        		stack2.push(root.val);
        		stack1.push(root);
        		root = root.right;
        	}
        	TreeNode cur = stack1.pop();
        	root = cur.left;
        }
        
        while(!stack2.isEmpty()) {
        	list.add(stack2.pop());
        }
        return list;
    }

层序遍历:

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> list = new ArrayList<List<Integer>>();   
    if(root == null) {
        	return list;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        
        queue.offer(root);
        
        while(!queue.isEmpty()) {
        	int levelNum = queue.size();
        	List<Integer> subList = new ArrayList<>();
        	
        	for(int i = 0;i < levelNum;i++) {
        		TreeNode cur = queue.poll();
        		subList.add(cur.val);
        		if(cur.left != null) {
        			queue.offer(cur.left);
        		}
        		if(cur.right != null)
        			queue.offer(cur.right);
        	}
        	list.add(subList);
        }
        return list;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值