KOKO-代码随想录算法训练营Day 14 |144 |145 | 94
文章目录
一、递归遍历
1.题目 二叉树的前中后序遍历
2.代码
前序:中左右:先取中间的值,再遍历左边直到结束,再取右边的值
public List<Integer> preorderTraversal(TreeNode root)
{
List<Integer> res=new ArrayList<>();
travsel(root,res);
return res;
}
private void travsel(TreeNode root,List<Integer> res)
{
if(root==null){
return ;
}
res.add(root.val);
travsel(root.left,res);
travsel(root.right,res);
}
中序遍历:左中右
遍历到空节点,回去取中间的值,再遍历右边到空节点
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
travel2(res,root);
return res;
}
private void travel(List<Integer> res, TreeNode root) {
if(root==null){
return;
}
travel(res,root.left);
res.add(root.val);
travel(res,root.right);
}
后序遍历:左右中
遍历左边到结束,遍历右边到结束,最后取中间的值
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
travel(root,list);
return list;
}
private void travel(TreeNode root, List<Integer> list) {
if(root==null){
return;
}
travel(root.left,list);
travel(root.right,list);
list.add(root.val);
}
3.总结
递归遍历,方法就是俩叉
递归遍历三部曲:
确定参数和返回值
确定终止条件
确定递归逻辑。
二、迭代遍历
1.题目 二叉树的前中后序遍历
2.代码
前序:中左右
入中间元素,弹出的时候把右节点和左节点放进去,因为栈先进后出,先记录左侧的值,记录弹出元素的值
public static List<Integer> preorderTraversal2(TreeNode root){
// 前序先将右边放入数组,因为弹的时候最后放进来的先弹出
List<Integer> list=new ArrayList<>();
if(root==null){
return null;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
TreeNode temp = st.pop();//弹出当前元素
list.add(temp.val);
if(temp.right!=null){
st.push(temp.right); //先压的后弹出
}
if(temp.left!=null){ //left会先弹出
st.push(temp.left);
}
}
return list;
}
中序:
中序需要找到左侧的叶子节点,因此定义一个指针push左侧节点,在为空的时候,弹出,记录值,将右侧节点作为当前node,
再判断右侧node是否为空,为空则弹栈
private static void travel2(List<Integer> res, TreeNode root){
if(root==null){
return;
}
Stack<TreeNode> st=new Stack<>();
TreeNode cur=root;//用指针去遍历二叉树,记录每个结点,到孩子结点后,栈弹出
while (!st.isEmpty()||cur!=null){
if(cur!=null){
st.push(cur);
cur=cur.left;
}else {
cur=st.pop();//弹出
res.add(cur.val);//数组记录
cur=cur.right; //叶子节点,叶子节点则弹出下一个元素
}
}
}
后序:中右左的反转(遍历顺序)
private void travel2(TreeNode root, List<Integer> list) {
if(root==null){
return;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
while (!st.isEmpty()){
TreeNode temp=st.pop();
list.add(temp.val);
if(temp.left!=null){
st.push(temp.left);
}
if(temp.right!=null){
st.push(temp.right);
}
}
Collections.reverse(list);
}
3.总结
后序即为前序遍历中右左的反转,则遍历时栈应先push root.left