题目
分别按照二叉树先序,中序和后序打印所有的节点。
示例 1:
输入: {1,2,3} 输出: [[1,2,3],[2,1,3],[2,3,1]]
解题思路:递归 [先序、中序、后序]
先序 中序 后序
import java.util.*;
public class Solution {
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
}
public int[][] threeOrders (TreeNode root) {
//三个集合,分别存储三种遍历结果
List<Integer> preList = new ArrayList<>();
List<Integer> inList = new ArrayList<>();
List<Integer> postList = new ArrayList<>();
//调用函数计算遍历结果
preOrder(root, preList);
inOrder(root, inList);
postOrder(root, postList);
//存放结果集
int[][] res = new int[3][preList.size()];
for(int i = 0; i < preList.size(); i++){
res[0][i] = preList.get(i);
res[1][i] = inList.get(i);
res[2][i] = postList.get(i);
}
//答案返回
return res;
}
// 先序遍历函数
public void preOrder(TreeNode root, List<Integer> list){
//特判
if(root == null) return;
//对左右子树进行递归的遍历
list.add(root.val);
preOrder(root.left, list);
preOrder(root.right, list);
}
// 中序遍历函数
public void inOrder(TreeNode root, List<Integer> list){
//特判
if(root == null) return;
//递归调用:对左右子树进行递归的遍历
inOrder(root.left, list);
list.add(root.val);
inOrder(root.right, list);
}
// 后序遍历函数
public void postOrder(TreeNode root, List<Integer> list){
if(root == null) return;
//递归调用:对左右子树进行递归的遍历
postOrder(root.left, list);
postOrder(root.right, list);
list.add(root.val);
}
}
解题思路:队列 [层次]
层次遍历的步骤是:
- 对于不为空的结点,先把该结点加入到队列中
- 从队中拿出结点,如果该结点的左右结点不为空,就分别把左右结点加入到队列中
- 重复以上操作直到队列为空
public class Solution{
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public void levelIterator(TreeNode root)
{
if(root == null) return ;
//1.创建队列
LinkedList<TreeNode> queue = new LinkedList<>();
TreeNode current = null;
queue.offer(root);//将根节点入队
while(!queue.isEmpty())
{
current = queue.poll(); //出队并获取队头元素
System.out.print(current.val +"-->"); //访问刚出队的对头元素
if(current.left != null) //如果当前节点的左节点不为空,将其入队
queue.offer(current.left);
if(current.right != null) //如果当前节点的右节点不为空,将其入队
queue.offer(current.right);
}
}
}
解题思路:双栈 [之字型]
给定的二叉树是 {1,2,3,#,#,4,5}
该二叉树之字形层序遍历的结果是
[ [1], [3,2], [4,5] ]
使用两个栈去实现。奇数行使用 stack1,偶数行使用 stack2。
注:使用 stack1 时,按照左右的顺序存储;使用 stack2 时,按照右左的顺序存储
ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
if(pRoot==null)
return list;
Stack<TreeNode> stack1 = new Stack<TreeNode>();
Stack<TreeNode> stack2 = new Stack<TreeNode>();
stack1.add(pRoot);
while(!stack1.empty() || !stack2.empty()){
ArrayList<Integer> li = new ArrayList<Integer>();
if(!stack1.empty()){
while(!stack1.empty()){
TreeNode node = stack1.pop();
li.add(node.val);
if(node.left!=null)
stack2.add(node.left);
if(node.right!=null)
stack2.add(node.right);
}
list.add(li);
}
else if(!stack2.empty()){
while(!stack2.empty()){
TreeNode node = stack2.pop();
li.add(node.val);
if(node.right!=null)
stack1.add(node.right);
if(node.left!=null)
stack2.add(node.left);
}
list.add(li);
}
}
return list;
}
解题思路:队列层次遍历+双端队列 [之字型]
复杂度分析
时间复杂度:,其中
为二叉树的节点数量,即 BFS 需循环
次,占用
;
- 双端队列的队首和队尾的添加和删除操作的时间复杂度均为  。
空间复杂度:
- 最差情况下,即当树为满二叉树时,最多有  个树节点 同时 在 **队列 **中
整理代码
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//1. 队列用于层次遍历
Queue<TreeNode> queue = new LinkedList<>();
//2. res 结果集用于存储结果
List<List<Integer>> res = new ArrayList<>();
//3. 先添加根节点
if(root != null) queue.add(root);
//# 当队列不为空
while(!queue.isEmpty()) {
//4. 双端队列,用于正序、倒序存储某一层
LinkedList<Integer> list = new LinkedList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
//由在结果集中的层次来断定正序、倒序
if(res.size() % 2 == 0)
list.addLast(node.val); // 偶数层 -> 队列尾部
else
list.addFirst(node.val); // 奇数层 -> 队列头部
//5. 将左右子树入队
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
res.add(list);
}
return res;
}
}
我的代码
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
//1. 队列用于层次遍历
Queue<TreeNode>queue=new LinkedList<>();
//2. res 结果集用于存储结果
ArrayList<ArrayList<Integer> > res = new ArrayList<>();
//3. 先添加根节点
if(pRoot != null) queue.add(pRoot);
while(!queue.isEmpty()){
int size=res.size()+1;
//4. 双端队列,用于正序、倒序存储某一层
LinkedList<Integer> list=new LinkedList<>();
for(int i=queue.size();i>0;i--){
TreeNode node=queue.poll();
//5. 与运算符判断奇偶
if((size&1)==1){
list.addLast(node.val);
}else{
list.addFirst(node.val);
}
if(node.left!=null)queue.add(node.left);
if(node.right!=null)queue.add(node.right);
}
//6. LinkedList 转换 ArrayList
res.add(new ArrayList<Integer>(list));
}
return res;
}
}