数据结构-二叉树(层次遍历的非递归与递归算法)

文章目录

思路

层次遍历与先序、中序、后序有什么直观的区别?

层次遍历实际就是 BFS 算法,广度优先搜索,先序、中序、后序实际上是 DFS 算法,深度优先搜索,这个很容易理解,一个一层一层的搜索,一个先找到左边最深的那个结点。

层次遍历与先/中/后序遍历的比较,DFS 和 BFS

先序,中序,后序遍历支持递归实现,也支持利用栈来实现,因为是深度 DFS 算法,所以用栈是没有问题的,递归也是一种栈的思想,我们这里可以想到 DFS 栈 递归 三者之间的关系。对比的层次遍历,我们应该想到 BFS 队列 二者之间的关系,一般来说 DFS 我们很容易直接想到用递归来实现,BFS 不属于递归的形式,我们用队列来处理,所以网上所给出的二叉树的层次遍历基本都是非递归利用队列的形式

若非要用递归实现

广度优先搜索不是递归的典型模型,我现在非要用递归实现,也行,那什么是递归?一个大问题转化小问题,小问题又转化更小问题…,最后有程序出口,那我们的大问题是什么呢?大问题就是遍历,怎么遍历呢?先遍历第一层,然后遍历下面所有的层,遍历下面所有的层又可以使用这个递归的方法,再遍历下面所有层中的第一层,然后再遍历下面所有层中除第一层的所有层…

递归出口是什么?

那么我们这个递归思路,它的出口是什么?怎么写?递归出口就是最下面一层的左右结点都为空,我们可以这样想,只要下面一层还有结点,哪怕是一个,就可以再调一次递归,否则该层递归直接出来返回上层递归

为什么用队列可以实现层次遍历?

我们试想,当我们想要层次遍历二叉树时,我们先可以把根结点放在队中,然后出队头,将左右子结点放在队列后,然后又出一个队头,再把这个队头的左右放在队尾,其实本质来说这不是一层一层的遍历,而是从上到下,从左到右一个结点一个结点的遍历

Java 实现

// 结点
class Node {
    int data;
    Node left = null;
    Node right = null;
}

// 二叉树
public class BinaryTree {
    // 根结点
    private Node root;
    // 输入的数组
    private int[] arr_in;
    // 输出的数组
    private int[] arr_out;
    // 记录数组下标
    private static int index;
    
    // 初始化
    public BinaryTree(int[] arr) {
        root = new Node();
        this.arr_in = arr;
        arr_out = new int[arr.length];
        index = 0;
    }
    
	// 层次遍历二叉树(用队列)
    public int[] levelTraversal(Node r) {
        if(r == null)
            return null;
        else {
            Queue queue = new LinkedList();
            Node node = r;
            queue.add(node);
            while(!LinkedList.isEmpty()) {
                Node top = queue.remove();
                arr_out[index++] = top.data;
                if (top.left)
                    queue.add(top.left);
                if (top.right)
                    queue.add(top.right);
            }
            index = 0;
            return arr_out;
        }
    }

	// 层次遍历二叉树(递归)
    public int[] levelTraversalRecursion(ArrayList al) {
        ArrayList arrayList = new ArrayList();
        for(Node n : al) {
            arr_out[index++] = n.data;
            if (n.left)
                arrayList.add(n.left);
            if (n.right)
                arrayList.add(n.right);
        }
        if (!arrayList.isEmpty())
        	levelTraversalRecursion(arrayList);
        if(index == arr_out.length)
            index = 0;
        return arr_out;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值