Java实现二叉树的前、中、后、层次遍历(递归+非递归)

一、二叉树的的遍历

构建二叉树的数据结构

class BinaryTree{
	int val;
	BinaryTree left;
	BinaryTree right;

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

1、前序遍历

1.1递归实现

实现思路:**先根节点,再左节点,最后右节点。**构建递归时有两个要点需要特别注意,一是递归结束的条件,一是递归表达式(即递归如何进行下去)。

class Traversal{
 public void preorderBT(BinaryTree root) {
    //结束条件
    if (root == null)
        return;
    System.out.print(root.val + " ");
    preorderBT(root.left);
    preorderBT(root.right);
 }
}
1.2 非递归实现

实现思路:需要用到栈这种数据结构(为什么是栈,不是别的数据结构)。因为递归实现的过程就是程序自己在处理圧栈和弹栈,改用非递归实现时,用栈模拟系统的圧栈与弹栈,就可以了。

import java.util.List;
import java.util.ArrayList;
import java.util.Stack;

public List<Integer> preorderBT1(BinaryTree root) {
      List<Integer> preorderResult = new ArrayList<>();
      Stack<BinaryTree> stack = new Stack<>();
      BinaryTree currentNode = root;
      while (currentNode != null || !stack.isEmpty()) {
      //对于前序遍历,需要一直往二叉树的左子树上走,直道左子树走完。在走左子树的过程中需要输出遇到节点的值
          while (currentNode != null) {
              preorderResult.add(currentNode.val);
              stack.push(currentNode);
              currentNode = currentNode.left;
          }
            //左边的节点都走完了,需要改变节点方向
          if (!stack.isEmpty()) {
              currentNode = stack.pop();
              currentNode = currentNode.right;
          }
      }
      return preorderResult;
}

2、中序遍历

2.1递归实现

实现思路:左子树—> 根结点 —> 右子树

public void inorderBT(BinaryTree root) {
    //结束条件
    if (root == null)
        return;
    inorderBT(root.left);
    System.out.print(root.val + " ");
    inorderBT(root.right);
 }
2.2非递归实现
 public List<Integer> inorderBT1(BinaryTree root) {
        List<Integer> inorderResult = new ArrayList<>();
        Stack<BinaryTree> stack = new Stack<>();
        BinaryTree currentNode = root;
        while (currentNode != null || !stack.isEmpty()) {
            //一直向左,但是先不打印经历的节点的值
            while (currentNode != null) {
                stack.push(currentNode);
                currentNode = currentNode.left;
            }
            //到达最左边,打印并改变方向
            if (!stack.isEmpty()) {
                currentNode = stack.pop();
                inorderResult.add(currentNode.val);
                currentNode = currentNode.right;
            }
        }
        return inorderResult;
    }

3、后序遍历

3.1递归实现

实现思路:左子树 —> 右子树 —> 根结点

public void postorderBT(BinaryTree root) {
     if (root == null)
         return;
     postorderBT(root.left);
     postorderBT(root.right);
     System.out.print(root.val+" ");
}
3.2非递归实现

妙用前序遍历的非递归可以实现后序遍历的非递归实现,这里需要注意几点改变:后序时,先遍历右,再遍历左,最后将得到的结果反向就好了。

public List<Integer> postorderBT1(BinaryTree root) {
     List<Integer> postorderResult = new ArrayList<>();
     Stack<BinaryTree> stack = new Stack<>();
     BinaryTree currentNode = root;
     while (currentNode != null || !stack.isEmpty()) {
         while (currentNode != null) {
             postorderResult.add(currentNode.val);
             stack.push(currentNode);
             currentNode = currentNode.right;
         }
         if (!stack.isEmpty()) {
             currentNode = stack.pop();
             currentNode = currentNode.left;
         }
     }
     Collections.reverse(postorderResult);
     return postorderResult;
}

4、层次遍历

层次遍历,需要用到队列这种数据结构

import java.util.List;
import java.util.ArrayList;
import java.util.Deque;
import java.util.ArrayDeque;

public List<Integer> levelOrderBT(BinaryTree root) {
        List<Integer> levelResult = new ArrayList<>();
        Deque<BinaryTree> deque = new ArrayDeque<>();
        if (root==null)
            return levelResult;
        deque.addLast(root);
        BinaryTree currentNode = root;
        while (!deque.isEmpty()){
            currentNode = deque.pollFirst();
            if (currentNode.left!=null)
                deque.addLast(currentNode.left);
            if (currentNode.right!=null)
                deque.addLast(currentNode.right);
            levelResult.add(currentNode.val);
        }
        return levelResult;
    }

5、测试

public class TraversalTest {
//构架测试用的二叉树
    public static BinaryTree createBT() {
        BinaryTree node0 = new BinaryTree(6);
        BinaryTree node1 = new BinaryTree(8);
        BinaryTree node2 = new BinaryTree(5);
        BinaryTree node3 = new BinaryTree(4);
        BinaryTree node4 = new BinaryTree(3);
        BinaryTree node5 = new BinaryTree(9);
        BinaryTree node6 = new BinaryTree(1);
        BinaryTree node7 = new BinaryTree(2);
        node0.left = node1;
        node0.right = node2;
        node1.left = node3;
        node1.right = node4;
        node2.right = node5;
        node4.left = node6;
        node4.right = node7;
        return node0;
 
    }
 
    static Traversal traversal = new Traversal();
 
    @Test
    public void preorderBT() {
        BinaryTree root = TraversalTest.createBT();
        traversal.preorderBT(root);
 
    }
    @Test
    public void preorderBT1() {
        BinaryTree root = TraversalTest.createBT();
        List<Integer> list = traversal.preorderBT1(root);
        System.out.println(list.toString());
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值