前中后遍历迭代遍历
1.怎么区分前中后遍历的??
**关键点:**根节点在哪个位置就是啥排序
不明白?
遍历顺序:
前序:中左右
中序:左中右
后续:左右中
看清楚了吗?当中的中字在哪个位置就是什么排序
2.话不多说,上代码
树节点的定义:
package 二叉树;
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(){};
TreeNode(int val)
{
this.val=val;
}
TreeNode(int val,TreeNode left,TreeNode right){
this.left=left;
this.right=right;
this.val=val;
}
}
2.1迭代排序
关键思想:就是入栈出栈
注意:
我的后序遍历算法思想:采用是前序遍历的逻辑,
**啥意思?**别急~~
前序遍历:中左右,入栈顺序:右左
这里我们将前序的算法入栈顺序改为中左右,这样出栈后为中右左,进行逆置数组,得到后序遍历:左右中
/**
* 三大遍历算法之迭代法
*/
//1.pre_order
//中左右,入栈:右左
public List<Integer> pre_order(TreeNode root){
//建立存储数据表
List<Integer> list=new ArrayList<>();
//判断是否有为空
if(root==null) return list;
//初始化栈
Stack<TreeNode> stack=new Stack();
//将根节点压入栈
stack.push(root);
//进行遍历
while(!stack.isEmpty()){
//根节点出栈
TreeNode node=stack.pop();
//存储数据
list.add(node.val);
//右节点压入栈
if(node.right!=null){
stack.push(node.right);
}
//判断右节点是否存在,存在压入栈
if(node.left!=null){
stack.push(node.left);
}
}
return list;
}
//mid_order
//order:左中右,入栈顺序:左中右
public List<Integer> mid_order(TreeNode root){
//建立存储表
List<Integer> list=new ArrayList();
//判断是否为空
if(root==null) return list;
//init stack
Stack<TreeNode> stack=new Stack<>();
//建立临时指针指向根节点
TreeNode node=root;
//进行遍历数据
while(node!=null||!stack.isEmpty()){
//寻找最左子节点
if(node!=null){
//父节点有子节点,父节点压入栈
stack.push(node);
//指针下移
node=node.left;
}else{
//发现结点相对父节点下面没有子节点了,进行相对父节点的弹栈操作
node=stack.pop();
//将弹栈的元素记录到存储表
list.add(node.val);
//遍历右子树
node=node.right;
}
}
return list;
}
//last_order
//左右中 入栈顺序:中右左
public List<Integer> last_order(TreeNode root){
//建立存储表
List<Integer> list=new ArrayList<>();
//判断是否为空
if(root==null) return list;
//初始化数组
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
//建立临时指针记录弹出栈的节点
TreeNode node=stack.pop();
list.add(node.val);
if(node.left!=null){
stack.push(node.left);
}
if(node.right!=null){
stack.push(node.right);
}
}
//进行翻转,得到后序遍历
Collections.reverse(list);
//返回数据
return list;
}
2.2 递归遍历
递归遍历注意:
1.确定参数和返回值
2.终止条件
3.单个递归的逻辑
package 二叉树;
import java.util.ArrayList;
import java.util.List;
public class 递归遍历的条件 {
/**
* 1.确定递归函数的参数和返回值
* 2.确定终止条件
* 3.确定单层递归的逻辑
*/
//前序遍历
public List<Integer> preorderTraversal(TreeNode root){
List<Integer> result=new ArrayList<Integer>();
preorder(root,result);
return result;
}
private void preorder(TreeNode root, List<Integer> result) {
if(root==null){
return;
}
result.add(root.val);
preorder(root.left,result);
preorder(root.right,result);
}
//中序遍历
public List<Integer> inorderTravelsal(TreeNode root){
List<Integer> res=new ArrayList<>();
inorder(root,res);
return res;
}
private void inorder(TreeNode root, List<Integer> res) {
if(root==null){
return;
}
inorder(root.left,res);
res.add(root.val);
inorder(root.right,res);
}
//后序遍历
public List<Integer> postorderTraversal(TreeNode root){
List<Integer> res=new ArrayList<Integer>();
postorder(root,res);
return res;
}
private void postorder(TreeNode root, List<Integer> res) {
if(root==null){
return;
}
postorder(root.left,res);
postorder(root.right,res);
res.add(root.val);
}
}