11.3 遍历二叉树方法整理

对二叉树遍历其实是将二叉树中的节点(非线性结构)以线性序列访问的过程。

如果二叉树是顺序结构(数组)保存的,直接遍历底层数组即可;
如果二叉树是用链表保存节点的,有下面两类遍历方式:

1) 深度优先遍历:先访问到树中最深层次的节点。有如下3种方式:

  1. 先(前)序遍历
  2. 中序遍历
  3. 后序遍历

2) 广度优先遍历:逐层访问每层节点,即先访问根节点,然后第二层节点……,所以又被称为按层遍历。

由于二叉树的定义本身就有“递归性”,所以深度优先遍历能非常方便地利用递归来遍历每个节点:依次遍历一个非空二叉树的根、左子树和右子树,就完成了整个二叉树的遍历。

1 深度优先遍历

1.1 先序遍历

先序遍历指先处理根节点,然后访问左右子树,遍历步骤如下:

1) 访问根节点

2) 递归遍历左子树

3) 递归遍历右子树

先序遍历的示例如下:

public List<TreeNode> preIterator(){
    return preIterator(root);
}

private List<TreeNode> preIterator(TreeNode node){
    List<TreeNode> list = new ArrayList<TreeNode>();
    // 处理根节点
    list.add(node);

    // 递归左子树
    if(node.left != null){
        list.addAll(preIterator(node.left));
    }

    // 递归右子树
    if(node.right != null){
        list.addAll(preIterator(node.right));
    }

    return list;
}

1.2 中序遍历

中序遍历指先处理左右子树,然后访问根节点、左右子树,遍历步骤如下:

扫描二维码关注公众号,回复: 868523 查看本文章

1) 递归遍历左子树

2) 访问根节点

3) 递归遍历右子树

中序遍历的示例如下:

public List<TreeNode> midIterator(){
    return midIterator(root);
}

private List<TreeNode> midIterator(TreeNode node){
    List<TreeNode> list = new ArrayList<TreeNode>();

    // 递归左子树
    if(node.left != null){
        list.addAll(midIterator(node.left));
    }

    // 处理根节点
    list.add(node);

    // 递归右子树
    if(node.right != null){
        list.addAll(midIterator(node.right));
    }

    return list;
}

1.3 后序遍历

后序遍历指最后处理根节点,遍历步骤如下:

1) 递归遍历左子树

2) 递归遍历右子树

3) 访问根节点

后序遍历的示例如下:

public List<TreeNode> postIterator(){
    return postIterator(root);
}

private List<TreeNode> postIterator(TreeNode node){
    List<TreeNode> list = new ArrayList<TreeNode>();

    // 递归左子树
    if(node.left != null){
        list.addAll(postIterator(node.left));
    }

    // 递归右子树
    if(node.right != null){
        list.addAll(postIterator(node.right));
    }

    // 处理根节点
    list.add(node);

    return list;
}

2 广度优先遍历

广度优先遍历可以通过队列来实现,步骤如下:

1) 创建一个队列,把根节点添加至队列;

2) 从队列中取出根节点,然后把该节点的左右节点添加至队列,若没有子节点,说明已经到达叶子节点;

3) 重复执行第二步,直到队列为空,此时说明所有的叶子节点都经过了队列,即完成了遍历。

对二叉树的广度遍历,利用Queue对象的特性,可以方便的实现二叉树的广度优先遍历,程序如下:

public List<TreeNode> breadthFirst(){
    Queue<TreeNode> nodeQueue = new ArrayDeque<TreeNode>();
    List<TreeNode> nodeList = new ArrayList<TreeNode>();
    if(root != null){
        // 添加根元素至队列
        nodeQueue.offer(root);
    }

    while(!nodeQueue.isEmpty()){
        // 将队列的“顶部”元素添加至list
        nodeList.add(nodeQueue.peak());
        TreeNode tn = nodeQueue.poll();

        // 将左子树节点加入队列
        if(tn.left != null){
            nodeQueue.offer(tn.left);
        }

        // 将右子树节点加入队列
        if(tn.right != null){
            nodeQueue.offer(tn.right);
        }
    }
    return nodeList;
}



参考资料:

疯狂Java:突破程序员基本功的16课-树和二叉树(第11课)

猜你喜欢

转载自blog.csdn.net/zhouxukun123/article/details/79673888
今日推荐