二叉树迭代遍历

  • 前中后用栈
  • 层次用队列
  • List:结果,用于记录遍历的节点val,顺序就是前序的顺序
  • Stack:用来确保节点按照前序进出
//代码步骤:建list存结果,判断root是否为null,建栈,root入栈,栈不为空的情况下循环(出栈,将结果放入res中,左右孩子进栈)


//前中后遍历不一致的写法
//前序遍历:节点“中-右-左”进栈,“中-左-右”出栈
public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if (root == null){
        return result;
    }
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()){
        TreeNode node = stack.pop();//当前节点出栈
        result.add(node.val);//val放入result中
        if (node.right != null){
            stack.push(node.right);//右子节点先进栈
        }
        if (node.left != null){
            stack.push(node.left);//左子节点后进栈
        }
    }
    return result;
}


//后序遍历,与前序相似,但节点“中-左-右”进栈,“中-右-左”出栈,然后反转result


//中序遍历,用一个指针遍历节点,栈处理节点,进栈“中-左-右”,出栈“左-中-右”,左节点进去后开始出
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){//当前节点不为null,继续指向左孩子
           stack.push(cur);
           cur = cur.left;//处理左孩子
       }else{//当前节点为null,说明已经找到最左边的节点了
           cur = stack.pop();//cur就是那个最左边的节点
           result.add(cur.val);//处理中间节点
           cur = cur.right;//处理右孩子
       }
    }
    return result;
}




//一致的写法:在需要处理的节点后面放一个null
public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new LinkedList<>();
    Stack<TreeNode> st = new Stack<>();
    if (root != null) st.push(root);
    while (!st.empty()) {
        TreeNode node = st.pop();
        if (node != null) {
          //根据遍历顺序调整入栈顺序
          if (node.right!=null) st.push(node.right);  // 添加右节点
          if (node.left!=null) st.push(node.left);    // 添加左节点
          st.push(node);                          // 添加中节点
          st.push(null); // 需要处理的节点后放null
        } else { // 遇到空节点,将下一个节点放进result
          st.pop();           // 将空节点弹出
          node = st.pop();    // 重新取出栈中元素
          result.add(node.val); // 加入到结果集
        }
    }
   return result;
}
//层次遍历
//代码步骤:生成List存结果,判断节点是否为null,建队列,root入队,队列不为空时循环(建存每层节点的List;记录当前队列长度,即该层节点数;循环将节点val存到result中并将左右孩子放入队列);将每层list加入result中
public List<List<Integer>> levelOrder(TreeNode root) {
  public List<List<Integer>> resList = new ArrayList<List<Integer>>();
  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);
    }
  return resList;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值