Java实现二叉树的搜索和遍历


树是一种常见的数据结构,由一系列节点和节点之间的关系组成。树的搜索和遍历是笔试和面试经常考的。最基本的树——二叉树,顾名思义,父节点最多只有两个子节点。我们先创建一个树节点类:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

树的搜索

在这里插入图片描述

深度优先搜索(Deep First Search)

深度优先搜索可以采用递归实现,代码如下:

List<Integer> visitList = new ArrayList();
public void dfs(TreeNode root){
    	if(root==null) return;
    	visitList.add(root.val);
    	dfs(root.left);
    	dfs(root.right);
    }

当然,也可以非递归的方式,不过此时要借助栈来实现:

public void dfs(TreeNode root){
       if(root==null){
             return;
       }
       Stack<TreeNode > stack = new Stack<TreeNode >();
       stack.push(node);
       while(!stack.isEmpty()){
             TreeNode rnode = stack.pop();
             visitlist.add(rnode.val);
             if(rnode.right!=null){
                   stack.push(rnode.right);
             }
             if(rnode.left!=null){
                   stack.push(rnode.left);
             }
       }
}

广度优先搜索(Breadth First Search)

广度优先搜索借助队列的FIFO特性实现,大致思路是:先搜索当前层的节点,然后将左子树和右子树添加到队列中,其Java代码如下(假设按层输出):

    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> res = new ArrayList();
        Queue<TreeNode> queue = new LinkedList();
        queue.add(root);     //向队列中添加根节点
        if(root==null) return res;
        while(!queue.isEmpty()){
            List<Integer> list = new ArrayList();
            Queue<TreeNode> temp = new LinkedList();
            while (!queue.isEmpty()) {
                TreeNode n = queue.remove();
                list.add(n.val);
                if (n.left != null)
                    temp.add(n.left);
                if (n.right != null)
                    temp.add(n.right);
            }
            queue = temp; 
            res.add(list);
        }
        return res;
    }

树的遍历

数的遍历方式可以按照父节点、左子节点、右子节点的访问顺序不同分为以下三种:前序遍历,中序遍历,后序遍历。

前序遍历(PreOrder)

先访问父节点,再访问左子节点,最后访问右子节点。那么对于上面那张图对应的二叉树的遍历顺序依次为:1,2,4,5,3,6,7。可以发现,树的深度度优先搜索访问顺序和前序遍历是一样的。对应的Java代码如下:

List<Integer> visitList = new ArrayList();
public void preOrder(TreeNode root){
    	if(root==null) return;
    	visitList.add(root.val);
    	preOrder(root.left);
    	preOrder(root.right);
    }

中序遍历(InOrder)

先访问左子节点,再访问父节点,最后访问右子节点。那么对于上面那张图对应的二叉树的遍历顺序依次为:4,2,5,1,6,3,7。对应的Java代码如下:

List<Integer> visitList = new ArrayList();
public void inOrder(TreeNode root){
    	if(root==null) return;
    	inOrder(root.left);
    	visitList.add(root.val);
    	inOrder(root.right);
    }

后序遍历(PostOrder)

先访问左子节点,再访问右子节点,最后访问父节点。那么对于上面那张图对应的二叉树的遍历顺序依次为:4,5,2,6,7,3,1。对应的Java代码如下:

List<Integer> visitList = new ArrayList();
public void postOrder(TreeNode root){
    	if(root==null) return;
    	postOrder(root.left);
    	postOrder(root.right);
    	visitList.add(root.val);
    }

不难发现,其实添加元素的位置的不同就对应了不同的遍历方式。

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