二叉树
递归遍历
前序、中序、后序的唯一区别:result.add()
的位置不同
防止空树:在边缘判断是否为空,而非递归逻辑处判断是否为空。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
result = new ArrayList<>();
preorder(root);
return result;
}
private List<Integer> result;
private void preorder(TreeNode node){
// 终止条件
if(node==null) return;
// 递归逻辑
result.add(node.val); // 前序
preorder(node.left);
preorder(node.right);
}
}
迭代遍历(用栈模拟递归)
前序
防止空树:在弹栈时处理空,而非压栈时处理空。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> st = new Stack<>();
// 访问
st.push(root);
List<Integer> result = new ArrayList<>();
TreeNode node;
while(!st.empty()){
// 处理
node = st.pop();
if(node==null) continue;
result.add(node.val);
// 访问
st.push(node.right);
st.push(node.left);
}
return result;
}
}
后序(前序的反转、反转
所谓的两次反转是指:
- 压栈时,左右翻转:
中右左
- 最终结果翻转:
左右中
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> st = new Stack<>();
// 访问
st.push(root);
List<Integer> result = new ArrayList<>();
TreeNode node;
while(!st.empty()){
// 处理
node = st.pop();
if(node==null) continue;
result.add(node.val);
// 访问
st.push(node.left);
st.push(node.right);
}
Collections.reverse(result);
return result;
}
}
中序(区别很大
按照要遍历的顺序依次压栈。依次取出来就是中序。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> st = new Stack<>();
List<Integer> result = new ArrayList<>();
// 访问
TreeNode node = root;
while(node!=null) { // 不把空节点压栈
st.push(node);
node = node.left;
}
while(!st.empty()){ // 因为要根据node是否为null进行判断
if(node==null) node = st.pop();
result.add(node.val);
node = node.right;
while(node!=null){
st.push(node);
node=node.left;
}
}
return result;
}
}
优化逻辑:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> st = new Stack<>();
List<Integer> result = new ArrayList<>();
// 访问
TreeNode node = root;
while(!st.empty()||node!=null){ // 因为要根据node是否为null进行判断
while(node!=null){
st.push(node);
node=node.left;
}
if(node==null) node = st.pop();
result.add(node.val);
node = node.right;
}
return result;
}
}
代码随想录版本:
// 中序遍历顺序: 左-中-右 入栈顺序: 左-右
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){
if (cur != null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
}
层序遍历(迭代、递归)
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
// order1(root, 0, result); // 因为数组下标从0开始,因此根节点深度设为0
order2(root, result);
return result;
}
// 递归
private void order1(TreeNode node, int depth, List<List<Integer>> result){
// 终止条件
if(node==null) return;
// 递归逻辑
if(result.size()<=depth){ // 保证有第二维
List<Integer> item = new ArrayList<>();
result.add(item);
}
result.get(depth).add(node.val);
if(node.left!=null) order1(node.left, depth+1, result);
if(node.right!=null) order1(node.right, depth+1, result);
}
// 队列
private void order2(TreeNode node, List<List<Integer>> result){
if(node==null) return;
Deque<TreeNode> dq = new LinkedList<>();
TreeNode cur;
dq.offer(node);
int depth = 0, count=1;
while(!dq.isEmpty()){
cur = dq.poll();
// 放入结果集
if(result.size()<=depth){
List<Integer> item = new ArrayList<>();
result.add(item);
}
result.get(depth).add(cur.val);
// 添加孩子到队列
if(cur.left!=null) dq.offer(cur.left);
if(cur.right!=null) dq.offer(cur.right);
// 改变深度与count
count--;
if(count==0){ // 下一层
depth++;
count = dq.size(); // 更新下一层的count
}
}
}
}
代码随想录:
- while的每个循环:遍历完该层的所有节点
//BFS--迭代方式--借助队列
public void checkFun02(TreeNode node) {
if (node == null) return;
Queue<TreeNode> que = new LinkedList<TreeNode>();
que.offer(node);
while (!que.isEmpty()) {
List<Integer> itemList = new ArrayList<Integer>();
int len = que.size();
while (len > 0) {
TreeNode tmpNode = que.poll();
itemList.add(tmpNode.val);
if (tmpNode.left != null) que.offer(tmpNode.left);
if (tmpNode.right != null) que.offer(tmpNode.right);
len--;
}
resList.add(itemList);
}
}