代码随想录day13 二叉树基础遍历
由于今天的所有题目都是和遍历相关,涉及到基础的二叉树数据结构,正好可以复习。
遍历顺序
前序: 递归的顺序为中间节点,左边节点和右边节点
中序: 递归的顺序为左边节点,中间节点和右边节点
后序: 递归的顺序为左边节点,右边节点和中间节点
递归
按照遍历的顺序递归相应的节点即可,例如前序递归,则先存储当前节点,在遍历左子节点和右子节点。
迭代
迭代我觉得是较为复杂的一个遍历方式,虽然可以节省性能,但是逻辑不是那么的清晰。
前序和后序
用栈来实现,我们先将根节点存入堆栈,然后当堆栈不为空时,记录下堆栈的顶部并弹出它,随后将顶部的子节点按右左的顺序存入堆栈中(不是左右的原因是因为堆栈是先进后出的,所以先存入右节点,左节点会先被弹出)。后序的思路是一样的,不过需要将结果反转一下
中序
中序的思路是稍微不太一样的,虽然还是用的堆栈,但是首先会把所有左子节点压入堆栈,然后在顶部弹出的时候对其右节点做同样的事。
【二刷】根节点需要一开始存入堆栈,还需要在循环外设置一个cur指针来记录每次遍历到的结点,在循环中每次先存入cur本身,随后优先遍历cur的左节点,等cur到树底的时候弹出后,移动到弹出结点的右节点,再次遍历其左节点,这样可以防止遗漏右节点包含的左子树。
统一迭代
这个是不太符合我的思维逻辑的一个迭代方式,所以就了解了一下。
层次迭代
这个则是使用队列,由于是从树的顶端每层从上往下遍历,因此我们需要用队列控制其进出顺序。
这个迭代的难点在于如何判断每一层的结束。我们可以通过一个变量来记录每一层包含多少个结点,可以通过队列长度来得到,注意,不能直接用que.size()作为循环截止条件,因为其会不断变化,正确做法是用一个变量来存储它,再进行遍历