日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【LeetCode笔记】94 144 145. 二叉树的前序、中序、后序遍历的迭代与递归(Java、dfs、迭代)

發布時間:2024/7/23 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LeetCode笔记】94 144 145. 二叉树的前序、中序、后序遍历的迭代与递归(Java、dfs、迭代) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一. 題目描述
  • 二. 代碼 & 思路
      • 1. 遞歸的寫法
      • 2. 迭代的寫法(本文重點來了)
          • 1) 前序
          • 2) 中序
          • 3) 后序

直接來個整合吧,也方便看。之前只寫了遞歸的,現在補上迭代的(迭代才是考點!)
是面試高頻題,要好好掌握好各自間的區分哦!

一. 題目描述

題目描述基本上一樣,就只展示中序的題干了

二. 代碼 & 思路

1. 遞歸的寫法

  • 這里比較簡單,就不贅述了,就是換換順序。
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/ class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {mid(ans);return ans;}// 前序void first(TreeNode root){if(root == null){return;}ans.add(root.val);first(root.left);first(root.right);}// 中序void mid(TreeNode now){if(now == null){return;}mid(now.left);ans.add(now.val);mid(now.right);}// 后序void last(TreeNode now){if(now == null){return;}last(now.left);last(now.right);ans.add(now.val);} }

2. 迭代的寫法(本文重點來了)

說實話,三份代碼簡直模版:while & if else & stack,寫的前五行代碼是一樣的

  • 首先明確一點,棧的作用
  • 前面的遞歸寫法,就是 JVM 隱式地幫我們進行了棧的操作
  • 迭代:用棧模仿虛擬機的調用過程
  • 前序 & 中序很像,后序相對難一點,需要維護一個 pre 結點
1) 前序
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> preorderTraversal(TreeNode root) {// 迭代:通過棧模擬虛擬機的遞歸結構Stack<TreeNode> myStack = new Stack<>();TreeNode now = root;// 前中后寫的前五行代碼都是一樣的while(now != null || !myStack.isEmpty()){// 非null情況:先加再說!入棧,然后直接往左走if(now != null){ans.add(now.val);myStack.push(now);now = now.left;}// null情況:那就走父結點的右邊!else {now = myStack.pop().right;}}return ans;} }
2) 中序
  • 和前序相比,都是一路向左,到頭了就取父結點的右邊
  • 不同之處在于,ans.add的位置,前序 & 中序分布在 if else 中
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {// 迭代:用棧模仿虛擬機的調用過程Stack<TreeNode> myStack = new Stack<>();TreeNode now = root;// 結束條件:當前結點已經走到底,并且棧中也無可用結點了while(now != null || !myStack.isEmpty()){// 非null情況:入棧,一路向左if(now != null){myStack.push(now);now = now.left;}// null情況:左到頭了,取出父節點,加入答案,然后從父結點的右結點繼續else{TreeNode temp = myStack.pop();ans.add(temp.val);now = temp.right;}}return ans;} }
3) 后序
  • 非null情況處理,和中序完全一樣
  • 唯一一個使用了peek的,也就是說:null情況不一定會pop
  • 代碼重點在于:null 情況部分,詳細見代碼
  • pre 的更新是從底向上的(有點抽象,結合代碼可能比較好理解)
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> postorderTraversal(TreeNode root) {Stack<TreeNode> myStack = new Stack<>();TreeNode now = root;// 相對于前序 & 中序,此處加了個 pre 結點,用來驗證右邊結點是否走過TreeNode pre = null;while(now != null || !myStack.isEmpty()){// 非null情況:先 push 當前結點,然后往左沖!if(now != null){myStack.push(now);now = now.left;}// null情況:沖到頭了else{// 注意這里是 peek,不一定 pop 掉now = myStack.peek();// 取答案的情況:父結點無右結點 Or 父節點的右結點已走過if(now.right == null || now.right == pre){ans.add(now.val);// 更新 pre 值為當前值,表示當前值已走過,供now的父節點使用pre = now;// pop 掉父節點myStack.pop();// 更新 now 為 null,下一次循環繼續peeknow = null;}// 可以繼續走右邊的情況else{now = now.right;}}}return ans;} }

總結

以上是生活随笔為你收集整理的【LeetCode笔记】94 144 145. 二叉树的前序、中序、后序遍历的迭代与递归(Java、dfs、迭代)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。