二叉树的递归和迭代遍历方式

1|0遍历二叉树的方法合集

2|0递归法

递归法的重点是明确递归的结果,考虑本次递归会产生什么

2|1前序遍历

public static void preOrderRecur(TreeNode head) { if (head == null) { return; } System.out.print(head.value + " "); preOrderRecur(head.left); preOrderRecur(head.right); }

2|2中序遍历

public static void preOrderRecur(TreeNode head) { if (head == null) { return; } preOrderRecur(head.left); System.out.print(head.value + " "); preOrderRecur(head.right); }

2|3后序遍历

public static void postOrderRecur(TreeNode head) { if (head == null) { return; } postOrderRecur(head.left); postOrderRecur(head.right); System.out.print(head.value + " "); }

3|0非递归法

非递归法就是模拟栈的运行,让你对栈的执行过程更加清楚

3|1前序遍历

前序遍历是根左右,这是出栈顺序

public List<Integer> preorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<Integer>(); Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode cur=root; while (cur!=null||!stack.isEmpty()) { while(cur!=null){ list.add(cur.val); stack.push(cur.right); cur=cur.left; } cur=stack.pop(); } return list; }

3|2中序遍历

前序遍历是左根右,这是出栈顺序

先将所有的左节点压入栈中,直到没有左节点,弹出栈顶,然后把弹出栈顶的右节点加入栈中

public List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while (cur != null || !stack.isEmpty()) { while(cur!=null){ stack.push(cur); cur=cur.left; } cur=stack.pop(); list.add(cur.val); cur=cur.right; } return list; }

3|3后序遍历

1|0法1:

后序遍历左右根是 根右左的倒序,所以将根右左的遍历顺序倒序即可

根节点入栈,加入左节点,加入右节点

1|0法2:

  1. 用一个指针cur标记当前退出的节点是什么。
  2. 后序遍历的过程中在遍历完左子树跟右子树cur都会回到根结点。所以当前不管是从左子树是右子树回到根结点
  3. 都不应该再操作了,应该退回上层。
  4. 如果是从右边再返回根结点,应该回到上层。

4|0总结

4|1前序遍历思路

栈S; p= root; while(p || S不空){ while(p){ 访问p节点; p的右子树入S; p = p的左子树; } p = S栈顶弹出; }

4|2中序遍历思路

栈S; p= root; while(p || S不空){ while(p){ p入S; p = p的左子树; } p = S.top 出栈; 访问p; p = p的右子树; }

4|3后序遍历思路

1|0法1:

栈S; p= root; while(p || S不空){ while(p){ 访问p节点; p的左子树入S; p = p的右子树; } p = S栈顶弹出; } 结果序列逆序;

1|0法2:

栈S; p= root; T<节点,True/False> : 节点标记; while(p || S不空){ while(p){ p入S; p = p的左子树; } while(S不空 且 T[S.top] = True){ 访问S.top; S.top出S; } if(S不空){ p = S.top 的右子树; T[S.top] = True; } }

__EOF__

本文作者程序员小宇
本文链接https://www.cnblogs.com/treasury/p/12826020.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   程序员小宇  阅读(291)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示