二叉树遍历方式
- 前序遍历:根左右
- 中序遍历:左根右
- 后序遍历:左右根
- 层序遍历:从上往下、从左到右
具体实现
- 递归遍历:使用递归方式
- 迭代遍历:使用迭代方式实现递归
- morris遍历
线索二叉树
介绍
在N
个节点的二叉树中,每个节点有2
个指针,所以一共有2N
个指针,除根节点以外,每个节点都有一个指针从它的父节点指向它,所以一种使用了N-1
个指针,所以剩下2N-(N-1)
也就是N+1
个空指针;
如果能利用这些空指针域来存放指向该节点的直接前驱或直接后继的指针,则可由此信息直接找到在该遍历次序的前去节点或后继节点,从而比递归遍历提高了速度,节省了建立系统递归栈所使用的存储空间;
这些被重新利用起来的空指针被称为线索(Thread)
,加上了线索的二叉树就是线索二叉树
实现思路
按某种次序遍历二叉树,在遍历过程中用线索取代空指针即可。以中序遍历为例,首先找到中序遍历的开始节点,然后利用线索依次查找后继节点即可。
由于充分的利用了空指针域的空间, 又保证了创建时的一次遍历就可以终生受用前驱、后继的信息,所以在实际问题中,如果所使用的二叉树需要经常遍历或查找节点时需要某种遍历的前驱和后继,线索二叉树是个不错的选择。
二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
解法一:深度优先搜索
思路
从根结点往下查找,先找左子树,直至左子树为空,再找右子树。找出最小的深度并返回+1
class Solution {
public int minDepth(TreeNode root) {
// 深度优先遍历
if(root == null){
return 0;
}
// 寻找叶子结点
if(root.left == null && root.right == null){
return 1;
}
int min = Integer.MAX_VALUE;
if(root.left!=null){
min = Math.min(min,minDepth(root.left));
}
if(root.right!=null){
min = Math.min(min,minDepth(root.right));
}
return min+1;
}
}
- 时间复杂度:O(N)
- 空间复杂度:O(log(N))
解法二:广度优先搜索
class Solution {
class QueueNode{
TreeNode node;
int depth;
public QueueNode(TreeNode node,int depth){
this.node = node;
this.depth = depth;
}
}
public int minDepth(TreeNode root) {
// 广度优先搜索
if(root == null){
return 0;
}
Queue<QueueNode> queue = new LinkedList<QueueNode>();
queue.offer(new QueueNode(root,1));
while(!queue.isEmpty()){
QueueNode nodeDepth = queue.poll();
TreeNode node = nodeDepth.node;
int depth = nodeDepth.depth;
if(node.left == null && node.right == null){
return depth;
}
if(node.left!=null){
queue.offer(new QueueNode(node.left,depth+1));
}
if(node.right!=null){
queue.offer(new QueueNode(node.right,depth+1));
}
}
return 0;
}
}
- 时间复杂度:O(N)
- 空间复杂度:O(N)
二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
解法一:递归
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>