前言
`
随着数据结构的学习,二叉树的遍历是不可避免的结构,今天带大家了解二叉树的三种遍历方式。
一、二叉树有哪三种遍历?
直接上图 (跟代表根节点,左右代表左子树右子树)
二、递归求三种遍历
递归不做过多解释,跟节点左右子树的顺序可判断递归顺序。以下拿leetcode上写代码。
前序遍历链接
中序遍历链接
后序遍历链接
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> List=new ArrayList();
public List<Integer> preorderTraversal(TreeNode root) {
if(root==null){
return List;
}
List.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return List;
}
}
2.中序遍历
class Solution {
List<Integer> res = new ArrayList<Integer>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root==null){
return res;
}
inorderTraversal(root.left);
res.add(root.val);
inorderTraversal(root.right);
return res;
}
}
3.后序遍历
class Solution {
List<Integer> res = new ArrayList<Integer>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root==null){
return res;
}
inorderTraversal(root.left);
res.add(root.val);
inorderTraversal(root.right);
return res;
}
}
代码大同小异,会一种三种都会,根据顺序自行做改变即可。
三、非递归求三种遍历
非递归的方法苦我久矣,我也是看了又看,写了有写,才勉强写好。这种写法就不得不提到栈,利用中间栈来存到List中。
4.前序遍历
根据栈的先进后出的特点,前序是跟左右顺序,入栈则需跟右左顺序,右数先进后出。
每次记录一下栈顶元素放入数组res中。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root ==null){
return res;
}
Stack<TreeNode> stack =new Stack<>();
stack.push(root);
while(!stack.empty()){
TreeNode cur=stack.peek();
stack.pop();
res.add(cur.val);
if(cur.right!=null){
stack.push(cur.right);
}
if(cur.left!=null){
stack.push(cur.left);
}
}
return res;
}
}
5.中序遍历
中序遍历比较特殊,不同于前序遍历的方法,先定义一个节点cur放入root,然后一路向左子树入栈直到为空,然后空就进行else。举个例子

走到4的左子树发现为空,进行else 把4放入数组并删除栈顶元素并访问4的右子树发现为空,在进入循环else此时cur等于节点2了,依次就行循环就能实现左跟右的遍历顺序。
class Solution {
List<Integer> res = new ArrayList<Integer>();
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
Stack<TreeNode> stack =new Stack<>();
TreeNode cur =root;
while(!stack.isEmpty()||cur!=null){
if(cur!=null){
stack.push(cur);
cur=cur.left;
}else{
cur=stack.pop();
res.add(cur.val);
cur=cur.right;
}
}
return res;
}
}
6.后序遍历
后序这里比较巧妙,左右跟顺序反转就是跟右左,发现与前序遍历就左右数顺序不一样,
所以这里我们只需在前序遍历改一下左右树入栈顺序,最后反转res即可。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root ==null){
return res;
}
Stack<TreeNode> stack =new Stack<>();
stack.push(root);
while(!stack.empty()){
TreeNode cur=stack.peek();
stack.pop();
res.add(cur.val);
if(cur.left!=null){
stack.push(cur.left);
}
if(cur.right!=null){
stack.push(cur.right);
}
}
Collections.reverse(res);
return res;
}
}
总结
如有错误欢迎指出。
231

被折叠的 条评论
为什么被折叠?



