博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉树前序中序后序遍历的非递归方法
阅读量:5704 次
发布时间:2019-06-17

本文共 4342 字,大约阅读时间需要 14 分钟。

hot3.png

二叉树遍历

通过递归方式遍历二叉树非常简单,只需要调整访问左子树、右子树、当前结点这三个语句的顺序,就可以实现三种遍历,但是毕竟需要递归调用,运算速度不及迭代方式、而且在面试中也会经常遇到,本问简单介绍几种迭代实现方式。

前序遍历(preorder)

1、 直接利用栈的FILO特性实现,后访问的先入栈

public void preorder(TreeNode root){        if(root == null)            return;        LinkedList
stack = new LinkedList<>(); stack.push(root); while(!stack.isEmpty()){ root = stack.pop(); visit(root); if(root.right != null) stack.push(root.right); if(root.left != null) stack.push(root.left); } }

每次先将右子树压栈,那么出栈时先访问左子树。

2、 dfs思想,优先向左子树访问,然后每次出栈后,再访问右子树

public void preorderTraversal(TreeNode root) {        LinkedList
stack = new LinkedList<>(); while(root != null || !stack.isEmpty()){ while(root != null){ stack.push(root); visit(root); root = root.left; } root = stack.pop(); root = root.right; } }

中序遍历(inorder)

1、 和前面前序遍历dfs思想一样,只是访问结点的位置变了

public void inorderTraversal(TreeNode root) {        LinkedList
stack = new LinkedList<>(); while(root != null || !stack.isEmpty()){ while(root != null){ stack.push(root); root = root.left; } root = stack.pop(); visit(root); root = root.right; } return ans; }

2、 思想同1,写法稍有不同

public void inorderTraversal(TreeNode root) {        LinkedList
stack = new LinkedList<>(); while(root != null || !stack.isEmpty()){ if(root != null){ stack.push(root); root = root.left; }else{ root = stack.pop(); visit(root); root = root.right; } } }

3、如果可以改变数的结构,那么可以每次把左右子树压栈后,将当前结点左右子结点设为空

public void inorderTraversal(TreeNode root) {        LinkedList
stack = new LinkedList<>(); if(root == null) return ; stack.push(root); while(!stack.isEmpty()){ root = stack.pop(); if(root.left == null && root.right == null){ visit(root); continue; } if(root.right != null) stack.push(root.right); stack.push(root); if(root.left != null) stack.push(root.left); root.left = null; root.right = null; } }

后序遍历(postorder)

1、可以利用同前序遍历的思想,依次访问结点、左子树、右子树,不过因为当前结点需要最后访问,所有可以把访问结果放在栈中,然后当遍历完成后从栈顶开始访问。

public List
postorderTraversal(TreeNode root) { LinkedList
stack = new LinkedList<>(); LinkedList
ans = new LinkedList<>(); while(root != null || !stack.isEmpty()){ while(root != null){ stack.push(root); ans.offerFirst(root.val); root = root.right; } root = stack.pop(); root = root.left; } return ans; }

2、同样也可以直接将左右子树压栈,结果也压榨,同preorder 1

public List
preorder(TreeNode root){ LinkedList
ans = new LinkedList<>(); if(root == null) return ans; LinkedList
stack = new LinkedList<>(); stack.push(root); while(!stack.isEmpty()){ root = stack.pop(); ans.offerFirst(root.val); if(root.right != null) stack.push(root.right); if(root.left != null) stack.push(root.left); } }

3、同中序遍历3,如果可以修改树,那么可以每次把左右子树压栈后,将当前结点左右子结点设为空

public void inorderTraversal(TreeNode root) {        LinkedList
stack = new LinkedList<>(); if(root == null) return ; stack.push(root); while(!stack.isEmpty()){ root = stack.pop(); if(root.left == null && root.right == null){ visit(root); continue; } if(root.right != null) stack.push(root.right); if(root.left != null) stack.push(root.left); stack.push(root); root.left = null; root.right = null; } }

转载于:https://my.oschina.net/u/2248183/blog/1805341

你可能感兴趣的文章
URL 中#号,? ,&的作用 (摘抄整理 链接为学习地址)
查看>>
树莓派:1组装启动
查看>>
android ExecutorService
查看>>
整理不错的kaggle链接(更新中)
查看>>
JDBC(2)Statement
查看>>
DRF教程2-请求和响应
查看>>
Asp.net Session 与Cookie的应用
查看>>
聊天 WH
查看>>
C#之接口
查看>>
20180401第九届蓝桥杯题解
查看>>
Python 爬虫 NewCnblogs (爬虫-Django-数据分析)
查看>>
结对项目--四则运算“软件”之升级版
查看>>
HDU 1010 Tempter of the Bone (DFS + 奇偶剪枝)
查看>>
模板模式(二十)
查看>>
Sae配置Java数据库连接
查看>>
【译】Spring 4 @Profile注解示例
查看>>
Python3笔记---变量和简单的数据类型
查看>>
WCF常见错误解决方法
查看>>
Console.WriteLine 不会输出到unity控制台
查看>>
中文参考文献如何导入到endnote中
查看>>